travis.rb: logs command fails: undefined method `each_pair' for # if the job has already finished and the logs archived

[dphillips@imac:~/src/presto master] travis logs 29248.9
displaying logs for prestodb/presto#29248.9
undefined method `each_pair' for #<String:0x00007fd51a053e70>
Did you mean?  each_char
for a full error report, run travis report --org


[dphillips@imac:~/src/presto master] travis report --org
System
Ruby:                     Ruby 2.5.0-p0
Operating System:         Mac OS X 10.13.3
RubyGems:                 RubyGems 2.7.4

CLI
Version:                  1.8.8
Plugins:                  none
Auto-Completion:          no
Last Version Check:       2018-02-08 18:38:34 -0800

Session
API Endpoint:             https://api.travis-ci.org/
Logged In:                as "electrum"
Verify SSL:               yes
Enterprise:               no

Endpoints
org:                      https://api.travis-ci.org/ (access token, current)

Last Exception
An error occurred running `travis logs --org`:
    NoMethodError: undefined method `each_pair' for #<String:0x00007fd51a053e70>
Did you mean?  each_char
        from /Users/dphillips/homebrew/lib/ruby/gems/2.5.0/gems/travis-1.8.8/lib/travis/client/session.rb:139:in `load'
        from /Users/dphillips/homebrew/lib/ruby/gems/2.5.0/gems/travis-1.8.8/lib/travis/client/session.rb:166:in `get'
        from /Users/dphillips/homebrew/lib/ruby/gems/2.5.0/gems/travis-1.8.8/lib/travis/client/session.rb:319:in `fetch_one'
        from /Users/dphillips/homebrew/lib/ruby/gems/2.5.0/gems/travis-1.8.8/lib/travis/client/session.rb:128:in `reload'
        from /Users/dphillips/homebrew/lib/ruby/gems/2.5.0/gems/travis-1.8.8/lib/travis/client/entity.rb:208:in `load_attribute'
        from /Users/dphillips/homebrew/lib/ruby/gems/2.5.0/gems/travis-1.8.8/lib/travis/client/entity.rb:54:in `block (2 levels) in attributes'
        from /Users/dphillips/homebrew/lib/ruby/gems/2.5.0/gems/travis-1.8.8/lib/travis/client/entity.rb:194:in `relation'
        from /Users/dphillips/homebrew/lib/ruby/gems/2.5.0/gems/travis-1.8.8/lib/travis/client/entity.rb:71:in `block (2 levels) in has'
        from /Users/dphillips/homebrew/lib/ruby/gems/2.5.0/gems/travis-1.8.8/lib/travis/client/artifact.rb:51:in `body'
        from /Users/dphillips/homebrew/lib/ruby/gems/2.5.0/gems/travis-1.8.8/lib/travis/cli/logs.rb:39:in `display_log'
        from /Users/dphillips/homebrew/lib/ruby/gems/2.5.0/gems/travis-1.8.8/lib/travis/cli/logs.rb:23:in `run'
        from /Users/dphillips/homebrew/lib/ruby/gems/2.5.0/gems/travis-1.8.8/lib/travis/cli/command.rb:198:in `execute'
        from /Users/dphillips/homebrew/lib/ruby/gems/2.5.0/gems/travis-1.8.8/lib/travis/cli.rb:64:in `run'
        from /Users/dphillips/homebrew/lib/ruby/gems/2.5.0/gems/travis-1.8.8/bin/travis:18:in `<top (required)>'
        from /Users/dphillips/homebrew/bin/travis:23:in `load'
        from /Users/dphillips/homebrew/bin/travis:23:in `<main>'


For issues with the command line tool, please visit https://github.com/travis-ci/travis.rb/issues.
For Travis CI in general, go to https://github.com/travis-ci/travis-ci/issues or email support@travis-ci.com.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 37
  • Comments: 46 (4 by maintainers)

Commits related to this issue

Most upvoted comments

Any progress on this? Still getting this when trying to do any travis command such as whoami or encrypt. “undefined method `each_pair’ for #String:0x00000001058240”

I have forked release 1.8.8 and applied the changes described in this thread, and it works for me 😃

https://github.com/textarcana/travis.rb/tree/fix-issue-578

The easiest way to install this is with bundler. Add the following to your Gemfile then run bundle install:

gem 'travis', :git => 'https://github.com/textarcana/travis.rb.git', :branch => 'fix-issue-578'

To figure out where bundler put the executable, type bundle info travis

Updated: Here is an even easier way to install

gem install specific_install

gem specific_install https://github.com/textarcana/travis.rb.git fix-issue-578

You should be able to use the travis command normally after that.

Seems there’s some recent PR activity.

Been making do with this ugliness, but hopefully not for much longer:

# Scrape 307 Temporary Redirect response for "Location" header field
# Drop non-printables, less ANSI \e and carriage (Tools::SafeString.colorized)
# "$@" means "the" "rest" (opts/args ...)
curl "$(travis logs --debug-http "$@" | grep ^Location: | cut -d \" -f 2)" | \
    sed 's/[^[:print:]\x1b\r]//g'

Any progress on this?

I looked through this issue again after venting earlier this morning.

This is not a solution in itself, it’s just the piece that I didn’t pick up while skimming through this issue and being unfamiliar with ruby.

The workaround is to patch client/session.rb yourself as suggested and described in https://github.com/travis-ci/travis.rb/issues/578#issuecomment-368142083 .

If you don’t know where to find the file run travis report --org. It’ll show you the stacktrace and a path like the following:

/var/lib/gems/2.3.0/gems/travis-1.8.8/lib/travis/client/session.rb

Then you add the class Hash at the top of the file and the three lines to the load method from from the comment above:

    if data.is_a?(String)
      return { log: { attributes: { body: data }}.to_struct('DummyEntity')}.to_struct('DummyLog')
    end

This issue seems to still happen with Ruby 2.5.1 and travis gem 1.8.9.

$ travis logs
displaying logs for {redacted}#2560.1
undefined method `each_pair' for #<String:0x00007faea91cc960>
Did you mean?  each_char
for a full error report, run travis report --pro

$ travis report --pro
System
Ruby:                     Ruby 2.5.1-p57
Operating System:         Mac OS X 10.13.6
RubyGems:                 RubyGems 2.7.6

CLI
Version:                  1.8.9
Plugins:                  none
Auto-Completion:          no
Last Version Check:       2018-09-04 09:50:21 -0700

Session
API Endpoint:             https://api.travis-ci.com/
Logged In:                as "eneko"
Verify SSL:               yes
Enterprise:               no

Endpoints
com:                      https://api.travis-ci.com/ (access token, current)
org:                      https://api.travis-ci.org/ (access token)

Last Exception
An error occurred running `travis logs --pro`:
    NoMethodError: undefined method `each_pair' for #<String:0x00007f7f40a22ff8>
Did you mean?  each_char
        from /usr/local/lib/ruby/gems/2.5.0/gems/travis-1.8.9/lib/travis/client/session.rb:139:in `load'
        from /usr/local/lib/ruby/gems/2.5.0/gems/travis-1.8.9/lib/travis/client/session.rb:166:in `get'
        from /usr/local/lib/ruby/gems/2.5.0/gems/travis-1.8.9/lib/travis/client/session.rb:319:in `fetch_one'
        from /usr/local/lib/ruby/gems/2.5.0/gems/travis-1.8.9/lib/travis/client/session.rb:128:in `reload'
        from /usr/local/lib/ruby/gems/2.5.0/gems/travis-1.8.9/lib/travis/client/entity.rb:208:in `load_attribute'
        from /usr/local/lib/ruby/gems/2.5.0/gems/travis-1.8.9/lib/travis/client/entity.rb:54:in `block (2 levels) in attributes'
        from /usr/local/lib/ruby/gems/2.5.0/gems/travis-1.8.9/lib/travis/client/entity.rb:194:in `relation'
        from /usr/local/lib/ruby/gems/2.5.0/gems/travis-1.8.9/lib/travis/client/entity.rb:71:in `block (2 levels) in has'
        from /usr/local/lib/ruby/gems/2.5.0/gems/travis-1.8.9/lib/travis/client/artifact.rb:51:in `body'
        from /usr/local/lib/ruby/gems/2.5.0/gems/travis-1.8.9/lib/travis/cli/logs.rb:39:in `display_log'
        from /usr/local/lib/ruby/gems/2.5.0/gems/travis-1.8.9/lib/travis/cli/logs.rb:23:in `run'
        from /usr/local/lib/ruby/gems/2.5.0/gems/travis-1.8.9/lib/travis/cli/command.rb:198:in `execute'
        from /usr/local/lib/ruby/gems/2.5.0/gems/travis-1.8.9/lib/travis/cli.rb:64:in `run'
        from /usr/local/lib/ruby/gems/2.5.0/gems/travis-1.8.9/bin/travis:18:in `<top (required)>'
        from /usr/local/bin/travis:23:in `load'
        from /usr/local/bin/travis:23:in `<main>'

For issues with the command line tool, please visit https://github.com/travis-ci/travis.rb/issues.
For Travis CI in general, go to https://github.com/travis-ci/travis-ci/issues or email support@travis-ci.com.

Thanks @20goto10, I’ve added your patch to my local files and ran into:

undefined method 'pending?' for nil:NilClass for a full error report, run travis report --org

NoMethodError: undefined method 'pending?' for nil:NilClass from /usr/local/rvm/gems/ruby-2.1.8/gems/travis-1.8.8/lib/travis/client/artifact.rb:51:inbody’`

I commented unless stream and job.pending? on line 51 (artifact.rb) and now I’m getting the logs again.

Hopefully they’ll address this issue soon.

I was running into this too, and added a patch you can insert in your own code to the “load” method, overriding it. It’s a total hack, but it works, which is enough for my purposes (an internal tool).

Note: I posted a solution earlier and then realized it was flawed, but the code below should work.

# There is a bug in the Travis gem (at least as recent as 1.8.8) that causes it to fail loading the log. The below overrides solve the problem.
class Hash
  def to_struct(struct_name)
    Struct.new(struct_name,*keys).new(*values)
  end
end

module Travis
  module Client
    class Session

      def load(data)
        result = {}
        if data.is_a?(String)
          return { log: { attributes: { body: data }}.to_struct('DummyEntity')}.to_struct('DummyLog')
        end
        (data || {}).each_pair do |key, value|
          entity = load_entity(key, value)
          result[key] = entity if entity
        end
        result
      rescue => e
        puts e.message
        puts e.backtrace.join("\n")
      end
    end
  end
end
# End Travis Overrides

It should work now without updating your client.

$ travis logs -r BanzaiMan/travis_production_test
displaying logs for BanzaiMan/travis_production_test#5226.1
Worker information
hostname: b65b0874-2c3e-411b-8729-b7699aea9fcf@1.worker-org-676f4fdd9b-gkwdb.gce-production-2
⋮
Skipping a deployment with the script provider because the current build is a pull request.

Done. Your build exited with 0.

Testing patch in textarcana#1 on travis gem 1.8.9 with Ruby 2.5.1 still results in same error & stacktrace posted by @eneko.

Function that fails is the line calling each_pair here:

 # /usr/local/lib/ruby/gems/2.5.0/gems/travis-1.8.9/lib/travis/client/session.rb:139:in `load'
  def load(data)
    result = {}
    (data || {}).each_pair do |key, value|
      entity      = load_entity(key, value)
      result[key] = entity if entity
    end
    result
  end

There is a String in one of these data objects which looks like the log output. This can be observed if you add some print lines right before this to print things out:

  def load(data)
    result = {}
    require 'pp'
    pp data.class
    pp data
    (data || {}).each_pair do |key, value|
      entity      = load_entity(key, value)
      result[key] = entity if entity
    end
    result
  end
Hash
[...SNIP...]
Hash
[...SNIP...]
displaying logs for username/reponame#NN.X
String
"travis_fold:start:step_upload_script\r\e[0K\e[33;1mUploading script\e[0m\r\n" +
"travis_fold:end:step_upload_script\r\e[0Ktravis_fold:start:worker_info\r\e[0K\e[33;1mWorker information\e[0m\n" +
"hostname: d516ec12-a65d-4454-ba88-daba63f36213@1.production-1-worker-org-gce-n8qm\n" +
"version: v4.2.0 https://github.com/travis-ci/worker/tree/7d17a81b8afc19da6842f1153f37371e859f4ccd\n" +
"instance: travis-job-1620ef03-61f5-425f-bc2d-edb70fd33148 travis-ci-garnet-trusty-1513287054-2ffda03 (via amqp)\n" +
"startup: 2m3.167309656s\n" +
"travis_fold:end:worker_info\r\e[0Ktravis_fold:start:system_info\r\e[0K\e[33;1mBuild system information\e[0m\r\n" +
"Build language: python\r\n" +
"Build group: edge\r\n" +
"Build dist: trusty\r\n" +
"Build id: 435742078\r\n" +
"Job id: 435742080\r\n" +
"Runtime kernel version: 4.4.0-104-generic\r\n" +
"travis-build version: e1590b459\r\n" +
"\e[34m\e[1mBuild image provisioning date and time\e[0m\r\n" +
"Thu Dec 14 21:58:09 UTC 2017\r\n" +
"\e[34m\e[1mOperating System Details\e[0m\r\n" +
"Distributor ID:\tUbuntu\r\n" +
"Description:\tUbuntu 14.04.5 LTS\r\n" +
"Release:\t14.04\r\n" +
"Codename:\ttrusty\r\n" +
[...SNIP...]

This object is a long ruby string with "text" + " more text " + ... representing the build log output. Assumptions based on this are that at some point maybe this was a type supporting .each_pair, maybe this code was different, or Travis API output changed?

Essentially the patch just forces the data into a Struct it won’t choke on later (which manifests as the whole ‘each_pair’ thing), whenever the data arrives as a String. So what I didn’t really look into is why it’s arriving sometimes as a String and sometimes not. I’m guessing there’s just a spot in the code somewhere where it usually takes the raw API results and puts them into some class, and in the case of these logs it isn’t doing it. But I didn’t have the patience to hunt that down at the time (and still don’t since my own use for this API is a simple internal helper app, nothing enterprise-y). Retrieving the logs would obviously be a major use case for this API so I’m pretty surprised this hasn’t been patched properly by now.

I don’t want to get in the way of progress but the original snippet I posted is really a hack. There should be a better solution to this problem. I just didn’t have the time to hunt through this code and work it out properly. That having been said… whatever works! Thanks for taking the time to put together a usable branch, @textarcana !

@textarcana Thanks, I applied those changes and it fixed the problem for me. Can finally show long logs again with travis logs -i 29039.2|less -R 🎉. Will you file it as PR here, so it can be merged upstream?

Same issue here 😦

Maybe I did it wrong but I also could not get the suggested “patch” to work

System
Ruby:                     Ruby 2.1.3-p242
Operating System:         Mac OS X 10.12.6
RubyGems:                 RubyGems 2.2.2

CLI
Version:                  1.8.9
Plugins:                  none
Auto-Completion:          no
Last Version Check:       2018-10-30 12:16:51 +0000

Session
API Endpoint:             https://api.travis-ci.com/
Logged In:                as "ChristopherHackett"
Verify SSL:               yes
Enterprise:               no

Endpoints
com:                      https://api.travis-ci.com/ (access token, current)
org:                      https://api.travis-ci.org/ (access token)

Last Exception
An error occurred running 'travis logs --pro':
    NoMethodError: undefined method 'each_pair' for #<String:0x007fa160bef808>

@textarcana Your patch that you made works like a charm for us too! I was wondering if you wanted to make a pull request on https://github.com/travis-ci/travis.rb so that your patch could be merged in with the official gem on RubyGems. We’d love to be able to use your patch on our own gems, but your patch would need to be merged into their original master branch.

my own use for this API is a simple internal helper app, nothing enterprise-y

heh. My use for this API is enterprisey like Starfleet 😃 so I definitely need the logs command to work.

I can see how it’s an easy workaround and that’s probably why no one fixed it up to now?

Anyway now that you have explained a bit I feel I could take a dive into fixing the actual problem (as time allows). 👍

@20goto10 yes I too have no idea what the patch does.

It seems others who have commented here before, have more knowledge of how the gem works?

If we can arrive at a patch that someone who knows how this thing works 😃 can say is acceptable, I would be more than happy to create a PR and shepherd it through the merging process!