{"record":{"id":"ca3531b4ff71203a","repo":"sipeed/picoclaw","slug":"autostart-is-not-supported-on-this-platform","errorCode":null,"errorMessage":"autostart is not supported on this platform","messagePattern":"autostart is not supported on this platform","errorType":"http","errorClass":"errAutoStartUnsupported","httpStatus":400,"severity":"warning","filePath":"web/backend/api/startup.go","lineNumber":32,"sourceCode":")\n\nconst (\n\tautoStartEntryName = \"PicoClawLauncher\"\n\tlaunchAgentLabel   = \"io.picoclaw.launcher\"\n)\n\ntype autoStartRequest struct {\n\tEnabled bool `json:\"enabled\"`\n}\n\ntype autoStartResponse struct {\n\tEnabled   bool   `json:\"enabled\"`\n\tSupported bool   `json:\"supported\"`\n\tPlatform  string `json:\"platform\"`\n\tMessage   string `json:\"message,omitempty\"`\n}\n\nvar errAutoStartUnsupported = errors.New(\"autostart is not supported on this platform\")\n\nfunc (h *Handler) registerStartupRoutes(mux *http.ServeMux) {\n\tmux.HandleFunc(\"GET /api/system/autostart\", h.handleGetAutoStart)\n\tmux.HandleFunc(\"PUT /api/system/autostart\", h.handleSetAutoStart)\n}\n\nfunc (h *Handler) handleGetAutoStart(w http.ResponseWriter, r *http.Request) {\n\tenabled, supported, message, err := h.getAutoStartStatus()\n\tif err != nil {\n\t\thttp.Error(w, fmt.Sprintf(\"Failed to read startup setting: %v\", err), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\tjson.NewEncoder(w).Encode(autoStartResponse{\n\t\tEnabled:   enabled,\n\t\tSupported: supported,\n\t\tPlatform:  runtime.GOOS,","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/web/backend/api/startup.go#L14-L50","documentation":"Platform-capability error from the autostart module. setAutoStart (startup.go:119-135) switches on runtime.GOOS and returns this sentinel only in the default branch, i.e. on any OS other than darwin, linux, windows. PUT /api/system/autostart turns it into HTTP 400 (startup.go:62-66); notably GET /api/system/autostart never errors — it just reports supported:false.","triggerScenarios":"PUT /api/system/autostart with {\"enabled\":true|false} while running a binary built for GOOS=freebsd, openbsd, plan9, js/wasm, etc.","commonSituations":"Cross-compiling the backend to an exotic target; running in a scratch container with an unusual GOOS; frontend code that assumes the toggle works everywhere because GET succeeded.","solutions":["Check GET /api/system/autostart and only show the toggle when the supported field is true","Run the backend on darwin, linux, or windows where launch-at-login is implemented","Hide or disable the autostart UI on unsupported platforms instead of sending the PUT","If you need autostart elsewhere, implement a new GOOS case in setAutoStart rather than catching the error"],"exampleFix":"// before\nawait fetch(`${api}/api/system/autostart`, {method: 'PUT', body: JSON.stringify({enabled: true})});\n\n// after\nconst st = await (await fetch(`${api}/api/system/autostart`)).json();\nif (!st.supported) throw new Error(`autostart unsupported on ${st.platform}`);\nawait fetch(`${api}/api/system/autostart`, {method: 'PUT', body: JSON.stringify({enabled: true})});","handlingStrategy":"validation","validationCode":"const st = await (await fetch(`${api}/api/system/autostart`)).json();\nif (!st.supported) {\n    ui.hideAutoStartToggle(st.message); // e.g. on freebsd/other GOOS\n    return;\n}","typeGuard":"func isAutoStartUnsupported(err error) bool {\n    return errors.Is(err, errAutoStartUnsupported)\n}","tryCatchPattern":"if err := h.setAutoStart(req.Enabled); err != nil {\n    if errors.Is(err, errAutoStartUnsupported) {\n        http.Error(w, err.Error(), http.StatusBadRequest)\n        return\n    }\n    http.Error(w, fmt.Sprintf(\"Failed to update startup setting: %v\", err), http.StatusInternalServerError)\n}","preventionTips":["Gate the autostart UI on the GET endpoint's supported field","Never assume launch-at-login works because GET succeeded — GET never errors, PUT does","Cross-compile checks: add a build/startup smoke test on the target GOOS","Add new platforms in setAutoStart's switch rather than catching the sentinel downstream"],"tags":["go","platform","autostart","capability"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}