{"record":{"id":"decc9ff18531c67a","repo":"dagger/dagger","slug":"file-name-q-must-not-contain-a-directory","errorCode":null,"errorMessage":"file name %q must not contain a directory","messagePattern":"file name %q must not contain a directory","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/file.go","lineNumber":501,"sourceCode":"\tcase persistedFileLazyKindChown:\n\t\tvar persisted persistedFileChownLazy\n\t\tif err := json.Unmarshal(payload, &persisted); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"decode persisted file chown lazy: %w\", err)\n\t\t}\n\t\tparent, err := loadPersistedObjectResultByResultID[*File](ctx, dag, persisted.ParentResultID, \"file chown parent\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &FileChownLazy{LazyState: NewLazyState(), Parent: parent, Owner: persisted.Owner}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"decode persisted file lazy payload: unsupported lazy kind %q\", lazyKind)\n\t}\n}\n\nfunc (lazy *FileBlobLazy) Evaluate(ctx context.Context, file *File) error {\n\treturn lazy.LazyState.Evaluate(ctx, \"File.blob\", func(ctx context.Context) error {\n\t\tif dir, _ := filepath.Split(lazy.Filename); dir != \"\" {\n\t\t\treturn fmt.Errorf(\"file name %q must not contain a directory\", lazy.Filename)\n\t\t}\n\t\tif err := ValidateFileName(lazy.Filename); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tpermissions := lazy.Permissions\n\t\tif permissions == 0 {\n\t\t\tpermissions = 0o644\n\t\t}\n\n\t\tquery, err := CurrentQuery(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tscratch, err := query.SnapshotManager().Scratch(ctx)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"create blob scratch snapshot: %w\", err)\n\t\t}\n\t\tnewRef, err := query.SnapshotManager().New(","sourceCodeStart":483,"sourceCodeEnd":519,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/core/file.go#L483-L519","documentation":"FileBlobLazy.Evaluate validates that the filename given to a blob-backed file (created via an API like File.withNewFile/with blob contents) contains no path separators. A blob file must be a single entry at the snapshot root; passing something like \"sub/dir/file.txt\" makes the lazy evaluation fail immediately. This is a direct input-validation error raised at evaluation time.","triggerScenarios":"Creating a new blob file where the name argument contains a directory component (filepath.Split yields a non-empty dir), e.g. `file.withNewFile(\"docs/readme.md\", contents)`.","commonSituations":"Users assuming withNewFile accepts relative paths inside the container; porting code that built nested paths; generating filenames by joining path fragments; templates that interpolate full paths.","solutions":["Pass only the base filename, then place the file in a directory using Directory.withNewFile instead of File APIs","Strip or split off the directory component before the call","Create the file via `directory.WithNewDirectory(\"docs\").WithNewFile(\"readme.md\", contents)`","Validate names client-side with ValidateFileName before calling the API"],"exampleFix":"// before\nfile := dir.WithNewFile(\"docs/readme.md\", contents)\n// after\ndir = dir.WithNewDirectory(\"docs\")\nfile := dir.WithNewFile(\"readme.md\", contents)","handlingStrategy":"validation","validationCode":"func validBlobName(name string) error {\n    if dir, _ := filepath.Split(name); dir != \"\" {\n        return fmt.Errorf(\"name %q must not contain a directory\", name)\n    }\n    return ValidateFileName(name)\n}\n// call before: validBlobName(\"readme.md\") instead of \"docs/readme.md\"","typeGuard":"func isBareFileName(name string) bool {\n    dir, _ := filepath.Split(name)\n    return dir == \"\" && name != \"\" && name != \".\" && name != \"..\"\n}","tryCatchPattern":"f, err := dir.WithNewFile(name, contents)\nif err != nil && strings.Contains(err.Error(), \"must not contain a directory\") {\n    dir = dir.WithNewDirectory(filepath.Dir(name))\n    f, err = dir.WithNewFile(filepath.Base(name), contents)\n}","preventionTips":["Only pass base filenames to file-with-content APIs; use Directory APIs for paths","Split joined paths and assert the dir component is empty before calling","Use ValidateFileName client-side in codegen or wrappers","Document path vs name semantics in internal helpers"],"tags":["validation","filename","path"],"backgroundTag":"filename-contains-path-separator","analyzedSha":"82ba2681dbe30d3547a1dc50ea495900ab5b6047","analyzedAt":"2026-09-05T07:21:37.930Z","contentChangedAt":"2026-09-05T07:21:37.930Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}