{"record":{"id":"0ca6475b3b67aa04","repo":"puppetlabs/puppet","slug":"the-argument-file-must-be-a-string-got-type","errorCode":null,"errorMessage":"The argument 'file' must be a String, got %{type}","messagePattern":"The argument 'file' must be a String, got %(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/pal/compiler.rb","lineNumber":158,"sourceCode":"    # @return [Puppet::Pops::Model::Program] returns a `Program` instance on success\n    #\n    def parse_string(code_string, source_file = nil)\n      unless code_string.is_a?(String)\n        raise ArgumentError, _(\"The argument 'code_string' must be a String, got %{type}\") % { type: code_string.class }\n      end\n\n      internal_evaluator.parse_string(code_string, source_file)\n    end\n\n    # Parses and validates a puppet language file and returns an instance of Puppet::Pops::Model::Program on success.\n    # If the content is not valid an error is raised.\n    #\n    # @param file [String] a file with puppet language content to parse and validate\n    # @return [Puppet::Pops::Model::Program] returns a `Program` instance on success\n    #\n    def parse_file(file)\n      unless file.is_a?(String)\n        raise ArgumentError, _(\"The argument 'file' must be a String, got %{type}\") % { type: file.class }\n      end\n\n      internal_evaluator.parse_file(file)\n    end\n\n    # Parses a puppet data type given in String format and returns that type, or raises an error.\n    # A type is needed in calls to `new` to create an instance of the data type, or to perform type checking\n    # of values - typically using `type.instance?(obj)` to check if `obj` is an instance of the type.\n    #\n    # @example Verify if obj is an instance of a data type\n    #   # evaluates to true\n    #   pal.type('Enum[red, blue]').instance?(\"blue\")\n    #\n    # @example Create an instance of a data type\n    #   # using an already create type\n    #   t = pal.type('Car')\n    #   pal.create(t, 'color' => 'black', 'make' => 't-ford')\n    #","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/pal/compiler.rb#L140-L176","documentation":"Compiler#parse_file requires the file argument to be a String path, even though the doc comment mentions Path. Passing a Pathname (very common in Ruby tooling) or an IO object raises ArgumentError naming the actual class. The path is handed straight to the parser, which expects a String.","triggerScenarios":"parse_file(Pathname.new('manifests/site.pp')) after using Pathname/Dir tooling; parse_file(File.open('site.pp')) passing the handle instead of the path; any code path where the path variable was built from Pathname operations.","commonSituations":"Tooling that uses Pathname throughout; confusion caused by the documented [Path, String] type versus the String-only implementation; wrapping PAL in apps that model paths as objects.","solutions":["Convert explicitly: parse_file(path.to_s)","Standardize on String paths at the PAL boundary in your wrapper code","If you hold an IO object, close it and pass the on-disk path instead"],"exampleFix":"# before\ncompiler.parse_file(Pathname.new('manifests/site.pp'))\n\n# after\ncompiler.parse_file(Pathname.new('manifests/site.pp').to_s)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"def string_path?(value)\n  value.is_a?(String) && !value.empty?\nend\n\nraise ArgumentError, 'file must be a String path' unless string_path?(file)","tryCatchPattern":null,"preventionTips":["Call .to_s on Pathname objects at API boundaries","Keep a thin wrapper around PAL calls that enforces String arguments"],"tags":["pal","type-check","argument","pathname","parse"],"backgroundTag":"wrong-argument-type","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}