sipeed/picoclaw · error
invalid format at line %d: %s
Error message
invalid format at line %d: %s
What it means
loadEnvFile parses each non-empty, non-comment line as KEY=value via strings.SplitN(line, "=", 2); a line without any '=' character is invalid and this error reports its 1-based line number and full content. Parsing stops at the first bad line, so earlier lines are discarded — the whole env file load fails.
Source
Thrown at pkg/mcp/manager.go:91
defer file.Close()
envVars := make(map[string]string)
scanner := bufio.NewScanner(file)
lineNum := 0
for scanner.Scan() {
lineNum++
line := strings.TrimSpace(scanner.Text())
// Skip empty lines and comments
if line == "" || strings.HasPrefix(line, "#") {
continue
}
// Parse KEY=value
parts := strings.SplitN(line, "=", 2)
if len(parts) != 2 {
return nil, fmt.Errorf("invalid format at line %d: %s", lineNum, line)
}
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])
if key == "" {
return nil, fmt.Errorf("invalid format at line %d: empty key", lineNum)
}
// Remove surrounding quotes if present
if len(value) >= 2 {
if (value[0] == '"' && value[len(value)-1] == '"') ||
(value[0] == '\'' && value[len(value)-1] == '\'') {
value = value[1 : len(value)-1]
}
}
envVars[key] = valueView on GitHub (pinned to 49183d7e8d)
Solutions
- Fix the reported line: give every entry the KEY=value form
- Prefix explanatory notes with # so they are treated as comments
- Remove shell syntax (source, export-without-=, set) — this is a plain env file, not a script
- Re-run: the message names the exact line number, so iterate until parsing passes
Example fix
# before (.env line 3 fails) # myserver config DB_HOST=localhost secret key goes here # after # myserver config DB_HOST=localhost SECRET_KEY=...
Defensive patterns
Strategy: type-guard
Validate before calling
func lintEnvFile(path string) error {
data, err := os.ReadFile(path)
if err != nil {
return err
}
for i, line := range strings.Split(string(data), "\n") {
line = strings.TrimSpace(line)
if line == "" || strings.HasPrefix(line, "#") {
continue
}
if !validEnvLine(line) {
return fmt.Errorf("line %d lacks KEY=value form: %s", i+1, line)
}
}
return nil
} Type guard
func validEnvLine(line string) bool {
key, value, found := strings.Cut(line, "=")
return found && strings.TrimSpace(key) != ""
} Prevention
- Lint env files in CI with a KEY=value parser before they ship
- Keep shell snippets out of env files — only # comments and KEY=value lines are supported
- Quote whole values with matching quotes only when needed; values may contain '=' but every line needs one
When it happens
Trigger: Lines like FOO (bare key), export FOO is fine only if it contains '=', but shell directives like source ~/.bashrc, set -e, or plain prose notes (not prefixed with #) all lack '=' and fail; a commented line whose leading # was lost (inline comments after values are kept as part of the value and are fine); a line-continuation backslash from a shell script pasted in.
Common situations: Pasting snippets from .bashrc into the env file; documenting entries with a bare word (FOO — the key) instead of FOO=; generated files where a value wrapped onto its own line; forgetting that only lines starting with # are comments.
Related errors
- failed to open env file: %w
- ${label} must be a JSON object.
- ${label}.${key} must be a string.
- MCP discovery requires at least one search method (BM25 or r
- MCP server names must be unique. Duplicates: ${duplicateName
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/5dab31ba64a9f740.
Report an issue: GitHub.