{"record":{"id":"b55ea21e43a01270","repo":"gastownhall/beads","slug":"agents-file-name-must-not-be-empty","errorCode":null,"errorMessage":"agents file name must not be empty","messagePattern":"agents file name must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/config.go","lineNumber":1170,"sourceCode":"// SafeAgentsFile returns the configured agents filename after validation.\n// If the stored config value is invalid (e.g. manually edited with traversal\n// paths), it falls back to DefaultAgentsFile and logs a warning.\nfunc SafeAgentsFile() string {\n\tname := AgentsFile()\n\tif err := ValidateAgentsFile(name); err != nil {\n\t\tdebug.Logf(\"config: agents.file %q failed validation (%v), using default\", name, err)\n\t\treturn DefaultAgentsFile\n\t}\n\treturn name\n}\n\n// ValidateAgentsFile checks that filename is safe to use as an agents file path.\n// It rejects absolute paths, path separators, names longer than 255 characters,\n// and non-markdown extensions. This is a pure string validation function — I/O\n// checks (e.g. symlink detection) are deferred to the file write layer.\nfunc ValidateAgentsFile(filename string) error {\n\tif filename == \"\" {\n\t\treturn fmt.Errorf(\"agents file name must not be empty\")\n\t}\n\tif len(filename) > 255 {\n\t\treturn fmt.Errorf(\"agents file name exceeds 255 characters\")\n\t}\n\tif strings.ContainsAny(filename, \"/\\\\\") {\n\t\treturn fmt.Errorf(\"agents file must be a simple filename without path separators, got %q\", filename)\n\t}\n\text := strings.ToLower(filepath.Ext(filename))\n\tif ext != \".md\" {\n\t\treturn fmt.Errorf(\"agents file must have .md extension, got %q\", ext)\n\t}\n\treturn nil\n}\n\n// getConfigList retrieves a list-typed configuration value from config.yaml,\n// accepting either the YAML list form (e.g. `types: { custom: [step, wisp] }`)\n// or the legacy comma-separated string form (e.g.\n// `types.custom = \"step,wisp\"`). Entries are trimmed; empty entries are","sourceCodeStart":1152,"sourceCodeEnd":1188,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/config/config.go#L1152-L1188","documentation":"ValidateAgentsFile performs pure string validation of a proposed agents file name before any I/O. An empty string cannot form a valid file path, so it is rejected first. SafeAgentsFile calls this before writing, so an empty name fails fast at the validation layer.","triggerScenarios":"Calling ValidateAgentsFile(\"\") directly, or SafeAgentsFile with an empty filename — commonly from an unset config value or an unfilled CLI flag.","commonSituations":"The agents-file setting is missing from config.yaml; a script passes an empty variable; a config key was renamed and the old lookup now returns \"\".","solutions":["Provide a non-empty filename, e.g. \"AGENTS.md\", when calling SafeAgentsFile.","Check the config key that supplies the filename and set it in config.yaml if missing.","Guard the call site: skip the write (or use the default name) when the value is an empty string."],"exampleFix":"// before\nname := cfg.GetString(\"agents.file\") // \"\"\nerr := config.SafeAgentsFile(name)\n// after\nname := cfg.GetString(\"agents.file\")\nif name == \"\" {\n    name = \"AGENTS.md\" // default\n}\nerr := config.SafeAgentsFile(name)","handlingStrategy":"validation","validationCode":"func validAgentsName(name string) bool {\n    return name != \"\"\n}\nif !validAgentsName(cfg.AgentsFile) {\n    cfg.AgentsFile = \"AGENTS.md\" // default\n}","typeGuard":null,"tryCatchPattern":"if err := config.SafeAgentsFile(name); err != nil {\n    if strings.Contains(err.Error(), \"must not be empty\") {\n        return fmt.Errorf(\"agents file not configured; set it in config.yaml or pass -agents-file\")\n    }\n    return err\n}","preventionTips":["Provide a sensible default (e.g. AGENTS.md) whenever the config value is empty.","Validate CLI flags with required-field checks before reaching the config layer.","After renaming config keys, grep for old lookups that now return empty strings.","Log the source of empty values (env vs config) to speed diagnosis."],"tags":["config","validation","filename","agents"],"backgroundTag":"invalid-filename","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}