juanfont/headscale · error

reading map responses from directory: %w

Error message

reading map responses from directory: %w

What it means

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.

Source

Thrown at cmd/mapresponses/main.go:52

				Run:      runOnline,
			},
			command.HelpCommand(nil),
		},
	}

	env := root.NewEnv(nil).MergeFlags(true)
	command.RunOrFail(env, os.Args[1:])
}

// runIntegrationTest executes the integration test workflow.
func runOnline(env *command.Env) error {
	if mapConfig.Directory == "" {
		return errDirectoryRequired
	}

	resps, err := mapper.ReadMapResponsesFromDirectory(mapConfig.Directory)
	if err != nil {
		return fmt.Errorf("reading map responses from directory: %w", err)
	}

	expected := integrationutil.BuildExpectedOnlineMap(resps)

	out, err := json.MarshalIndent(expected, "", "  ")
	if err != nil {
		return fmt.Errorf("marshaling expected online map: %w", err)
	}

	os.Stderr.Write(out)
	os.Stderr.Write([]byte("\n"))

	return nil
}

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Verify the directory exists and contains files: `ls <dir>` — it must hold MapResponse JSON captures
  2. Validate each file parses: `for f in <dir>/*; do jq . "$f" >/dev/null || echo "bad: $f"; done`
  3. Re-capture the map responses with the current headscale version if the schema changed
  4. Check the wrapped error — it typically names the offending file path
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(mapConfig.Directory)
if err != nil || !info.IsDir() {
    return fmt.Errorf("map responses directory missing: %s", mapConfig.Directory)
}
entries, _ := os.ReadDir(mapConfig.Directory)
if len(entries) == 0 {
    return fmt.Errorf("map responses directory empty: %s", mapConfig.Directory)
}

Try / catch

resps, err := mapper.ReadMapResponsesFromDirectory(dir)
if err != nil {
    // wrapped error names the offending file; validate individually to isolate it
    return fmt.Errorf("reading map responses from directory: %w", err)
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15). Data as JSON: /api/errors/033794f05d68d0b8. Report an issue: GitHub.