{"record":{"id":"bac87c1de4f6d2ff","repo":"microsoft/typescript-go","slug":"w-failed-to-stop-cpu-profile-w","errorCode":null,"errorMessage":"%w: failed to stop CPU profile: %w","messagePattern":"%w: failed to stop CPU profile: %w","errorType":"error_code","errorClass":"ErrClientError","httpStatus":null,"severity":"error","filePath":"internal/api/session.go","lineNumber":882,"sourceCode":"\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown method: %s\", method)\n\t}\n}\n\nfunc (s *Session) handleStartCPUProfile(_ context.Context, params *ProfileParams) (any, error) {\n\tif params == nil || params.Dir == \"\" {\n\t\treturn nil, fmt.Errorf(\"%w: dir is required\", ErrClientError)\n\t}\n\tif err := s.cpuProfiler.StartCPUProfile(params.Dir); err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: failed to start CPU profile: %w\", ErrClientError, err)\n\t}\n\treturn nil, nil\n}\n\nfunc (s *Session) handleStopCPUProfile(_ context.Context) (*ProfileResult, error) {\n\tfilePath, err := s.cpuProfiler.StopCPUProfile()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: failed to stop CPU profile: %w\", ErrClientError, err)\n\t}\n\treturn &ProfileResult{File: filePath}, nil\n}\n\nfunc (s *Session) handleSaveHeapProfile(_ context.Context, params *ProfileParams) (*ProfileResult, error) {\n\tif params == nil || params.Dir == \"\" {\n\t\treturn nil, fmt.Errorf(\"%w: dir is required\", ErrClientError)\n\t}\n\tfilePath, err := pprof.SaveHeapProfile(params.Dir)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: failed to save heap profile: %w\", ErrClientError, err)\n\t}\n\treturn &ProfileResult{File: filePath}, nil\n}\n\n// HandleNotification implements Handler.\nfunc (s *Session) HandleNotification(ctx context.Context, method string, params json.Value) error {\n\t// TODO: Implement notification handling","sourceCodeStart":864,"sourceCodeEnd":900,"githubUrl":"https://github.com/microsoft/typescript-go/blob/1bcfa18d79a3be41772223d5c05dfe4480e614ff/internal/api/session.go#L864-L900","documentation":"stopCPUProfile forwarded the profiler error, wrapped in ErrClientError. The typical cause is stopping when no CPU profile is active (the start failed earlier or was never issued), or an error finalizing/flushing the profile file when profiling stops.","triggerScenarios":"Calling stopCPUProfile after a startCPUProfile that returned an error; calling stop twice; disk/full-permission problems flushing the profile on stop.","commonSituations":"Error from start swallowed by client code, so the caller believes a profile is running; shutdown hooks that unconditionally stop profiling; profiling guards implemented with bare flags that drift from real profiler state.","solutions":["Only call stopCPUProfile after a startCPUProfile that returned success","Track start/stop state client-side and reset it on any error","Treat a stop error as non-fatal during shutdown; capture the file path only on success"],"exampleFix":"// before\nstartCPUProfile(dir) // error ignored\nstopCPUProfile() // \"failed to stop\"\n\n// after\nif err := startCPUProfile(dir); err != nil { return err }\nres, err := stopCPUProfile() // only reached when start succeeded","handlingStrategy":"validation","validationCode":"// Track profiler state; only stop what you successfully started.\nvar profiling atomic.Bool\nif err := startCPUProfile(dir); err != nil { return err }\nprofiling.Store(true)\ndefer func() {\n    if profiling.CompareAndSwap(true, false) {\n        _, _ = stopCPUProfile()\n    }\n}()","typeGuard":"func shouldStopCPU(profiling bool) bool { return profiling }","tryCatchPattern":"if _, err := session.HandleRequest(ctx, string(api.MethodStopCPUProfile), nil); err != nil {\n    // Most common: no active profile. Treat as non-fatal during shutdown; log and continue.\n    log.Printf(\"stopCPUProfile: %v\", err)\n}","preventionTips":["Reset profiling state whenever startCPUProfile returns an error","Make shutdown stop handlers idempotent so double-stop cannot occur","Do not treat stop failures as fatal; the profile file may already be usable"],"tags":["profiling","cpu-profile","lifecycle","api"],"backgroundTag":null,"analyzedSha":"1bcfa18d79a3be41772223d5c05dfe4480e614ff","analyzedAt":"2026-08-16T02:12:00.115Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}