{"record":{"id":"c81f6bf553f8374f","repo":"sipeed/picoclaw","slug":"invalid-env-assignment-q-key-cannot-be-empty","errorCode":null,"errorMessage":"invalid env assignment %q: key cannot be empty","messagePattern":"invalid env assignment %q: key cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/picoclaw/internal/mcp/helpers.go","lineNumber":226,"sourceCode":"\t}\n\tsort.Strings(names)\n\treturn names\n}\n\nfunc parseEnvAssignments(values []string) (map[string]string, error) {\n\tif len(values) == 0 {\n\t\treturn nil, nil\n\t}\n\n\tenv := make(map[string]string, len(values))\n\tfor _, entry := range values {\n\t\tkey, value, found := strings.Cut(entry, \"=\")\n\t\tif !found {\n\t\t\treturn nil, fmt.Errorf(\"invalid env assignment %q: expected KEY=value\", entry)\n\t\t}\n\t\tkey = strings.TrimSpace(key)\n\t\tif key == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"invalid env assignment %q: key cannot be empty\", entry)\n\t\t}\n\t\tenv[key] = value\n\t}\n\n\treturn env, nil\n}\n\nfunc parseHeaderAssignments(values []string) (map[string]string, error) {\n\tif len(values) == 0 {\n\t\treturn nil, nil\n\t}\n\n\theaders := make(map[string]string, len(values))\n\tfor _, entry := range values {\n\t\tkey, value, found := strings.Cut(entry, \":\")\n\t\tif !found {\n\t\t\tkey, value, found = strings.Cut(entry, \"=\")\n\t\t}","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/cmd/picoclaw/internal/mcp/helpers.go#L208-L244","documentation":"Second guard of parseEnvAssignments (helpers.go:224-227): the entry contained '=' but the key side is empty after trimming. The parser deliberately rejects '=value' and ' =value' rather than storing a nameless variable.","triggerScenarios":"`-e =foo`, `-e \" =foo\"`, or a paste that put the value before the equals sign.","commonSituations":"Copy-paste artifacts; retyping an assignment and swapping the sides; macros/snippets emitting a leading space.","solutions":["Put the variable name before the equals sign: -e API_KEY=secret","Inspect the exact argument with printf '%s\\n' \"$PAIR\" | cat -A to reveal leading whitespace"],"exampleFix":"# before\npicoclaw mcp add s ./server -e \"=secret\"\n# after\npicoclaw mcp add s ./server -e \"API_KEY=secret\"","handlingStrategy":"validation","validationCode":"validate_env() {\n  local pair=$1\n  [[ $pair == *=* ]] || { echo \"need KEY=value\" >&2; return 1; }\n  local key=${pair%%=*}\n  [[ -n \"${key//[[:space:]]/}\" ]] || { echo \"empty key in '$pair'\" >&2; return 1; }\n}\nvalidate_env \"$pair\" && picoclaw mcp add \"$name\" \"$target\" -e \"$pair\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the key flush against '=' with no leading whitespace","Check paste artifacts with cat -A when assignments misbehave"],"tags":["cli","flags","environment","validation"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}