{"record":{"id":"845647f02541df79","repo":"argoproj/argo-workflows","slug":"failed-to-write-initial-status-marker-w","errorCode":null,"errorMessage":"failed to write initial status marker: %w","messagePattern":"failed to write initial status marker: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/argoexec/commands/supervisor.go","lineNumber":190,"sourceCode":"\tnames := make([]wfv1.ArtifactPluginName, 0, len(raw))\n\tfor _, p := range raw {\n\t\tnames = append(names, wfv1.ArtifactPluginName(p))\n\t}\n\treturn names\n}\n\n// startStatusHeartbeat writes an initial RUNNING status, then rewrites it every\n// supervisorHeartbeatInterval on a background goroutine until the returned stop\n// function is called. Each rewrite advances the marker's mtime, which main's\n// emissary uses to distinguish a live (but slow) supervisor from a dead one.\n//\n// The initial write is synchronous so a broken shared mount fails fast (its\n// error is returned). stop() cancels the goroutine and blocks until it has\n// exited, guaranteeing no heartbeat write can race the terminal status write\n// that follows it.\nfunc startStatusHeartbeat(ctx context.Context) (stop func(), err error) {\n\tif err := writeRunningStatus(); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to write initial status marker: %w\", err)\n\t}\n\thbCtx, cancel := context.WithCancel(ctx)\n\tdone := make(chan struct{})\n\tgo func() {\n\t\tdefer close(done)\n\t\tticker := time.NewTicker(supervisorHeartbeatInterval)\n\t\tdefer ticker.Stop()\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-hbCtx.Done():\n\t\t\t\treturn\n\t\t\tcase <-ticker.C:\n\t\t\t\tif err := writeRunningStatus(); err != nil {\n\t\t\t\t\tlogging.RequireLoggerFromContext(ctx).WithError(err).Warn(ctx, \"failed to write status heartbeat\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/cmd/argoexec/commands/supervisor.go#L172-L208","documentation":"startStatusHeartbeat writes a synchronous initial \"running\" status marker to a path shared between the supervisor and main containers before starting a periodic heartbeat goroutine. If that initial write fails, the error is wrapped as \"failed to write initial status marker\" and returned so callers fail fast — a broken shared mount would otherwise leave the main container waiting on a status that never appears.","triggerScenarios":"A supervisor container calling startStatusHeartbeat where writeRunningStatus() returns an error on the first write — /var/run/argo shared volume missing, read-only, or full; permission denied on the status file path.","commonSituations":"Init-less (supervisor) workflows where the emptyDir shared between main and supervisor containers is misconfigured or not mounted in the supervisor; restricted pod security policies denying writes; disk-full nodes.","solutions":["Inspect the wrapped cause (EACCES/ENOENT/ENOSPC) to identify the filesystem problem","Ensure the shared status volume is mounted at the expected /var/run/argo path in the supervisor container","Make the mount writable by the argoexec user (fsGroup/securityContext adjustments)","Free storage or raise ephemeral-storage limits if ENOSPC"],"exampleFix":"// before: supervisor container missing the shared mount\ncontainers:\n  - name: main\n    volumeMounts: []\n// after\ncontainers:\n  - name: main\n    volumeMounts:\n      - name: var-run-argo\n        mountPath: /var/run/argo\n      # supervisor sidecar must mount the same volume\n","handlingStrategy":"try-catch","validationCode":"// fail fast in CI/dev with a supervisor smoke test:\n// kubectl exec <pod> -c main -- test -w /var/run/argo/status-path-dir","typeGuard":null,"tryCatchPattern":"stop, err := startStatusHeartbeat(ctx)\nif err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) {\n        // mount/permission problem on the shared status volume — fix before main starts\n    }\n    return err\n}","preventionTips":["Ensure both supervisor and main containers mount the same shared volume for status files","Grant write access via fsGroup/securityContext in the pod spec","Keep an eye on disk space where status markers are written","Test the init-less supervisor path after any executor or volume-config change"],"tags":["go","argo-executor","supervisor","filesystem","heartbeat"],"backgroundTag":"file-write-failed","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}