{"record":{"id":"033794f05d68d0b8","repo":"juanfont/headscale","slug":"reading-map-responses-from-directory-w","errorCode":null,"errorMessage":"reading map responses from directory: %w","messagePattern":"reading map responses from directory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/mapresponses/main.go","lineNumber":52,"sourceCode":"\t\t\t\tRun:      runOnline,\n\t\t\t},\n\t\t\tcommand.HelpCommand(nil),\n\t\t},\n\t}\n\n\tenv := root.NewEnv(nil).MergeFlags(true)\n\tcommand.RunOrFail(env, os.Args[1:])\n}\n\n// runIntegrationTest executes the integration test workflow.\nfunc runOnline(env *command.Env) error {\n\tif mapConfig.Directory == \"\" {\n\t\treturn errDirectoryRequired\n\t}\n\n\tresps, err := mapper.ReadMapResponsesFromDirectory(mapConfig.Directory)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"reading map responses from directory: %w\", err)\n\t}\n\n\texpected := integrationutil.BuildExpectedOnlineMap(resps)\n\n\tout, err := json.MarshalIndent(expected, \"\", \"  \")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"marshaling expected online map: %w\", err)\n\t}\n\n\tos.Stderr.Write(out)\n\tos.Stderr.Write([]byte(\"\\n\"))\n\n\treturn nil\n}\n","sourceCodeStart":34,"sourceCodeEnd":67,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/cmd/mapresponses/main.go#L34-L67","documentation":"mapper.ReadMapResponsesFromDirectory failed while loading captured MapResponse JSON files for the mapresponses tool. The function walks the given directory, reads each file, and unmarshals it as a headscale MapResponse; it errors when the directory is missing/unreadable, contains files that are not valid MapResponse JSON, or a read fails. This feeds BuildExpectedOnlineMap, so bad input here blocks expected-output generation for the online integration check.","triggerScenarios":"mapConfig.Directory pointing at a non-existent path, an empty or non-directory path, or a directory containing malformed/truncated MapResponse JSON (partial capture, hand-edited file, wrong schema field names).","commonSituations":"Pointing --directory at the wrong folder (e.g. control_logs/ instead of the captured mapresponses dir); captures made by an older headscale version whose JSON schema changed; files truncated by disk-full during capture.","solutions":["Verify the directory exists and contains files: `ls <dir>` — it must hold MapResponse JSON captures","Validate each file parses: `for f in <dir>/*; do jq . \"$f\" >/dev/null || echo \"bad: $f\"; done`","Re-capture the map responses with the current headscale version if the schema changed","Check the wrapped error — it typically names the offending file path"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"info, err := os.Stat(mapConfig.Directory)\nif err != nil || !info.IsDir() {\n    return fmt.Errorf(\"map responses directory missing: %s\", mapConfig.Directory)\n}\nentries, _ := os.ReadDir(mapConfig.Directory)\nif len(entries) == 0 {\n    return fmt.Errorf(\"map responses directory empty: %s\", mapConfig.Directory)\n}","typeGuard":null,"tryCatchPattern":"resps, err := mapper.ReadMapResponsesFromDirectory(dir)\nif err != nil {\n    // wrapped error names the offending file; validate individually to isolate it\n    return fmt.Errorf(\"reading map responses from directory: %w\", err)\n}","preventionTips":["Point --directory at a directory of freshly captured MapResponse JSON, not control_logs/","jq-validate every captured file after capture and before processing","Re-capture after upgrading headscale — the MapResponse schema moves between versions"],"tags":["mapresponses","json","filesystem","integration-tests"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}