{"record":{"id":"5dd45d55d04ef33a","repo":"apache/beam","slug":"side-input-closed","errorCode":null,"errorMessage":"side input closed","messagePattern":"side input closed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/harness/statemgr.go","lineNumber":487,"sourceCode":"\t\tinstID:    instID,\n\t\tkey:       key,\n\t\tch:        ch,\n\t\twriteType: writeTypeClear,\n\t}\n}\n\nfunc (r *stateKeyReader) Read(buf []byte) (int, error) {\n\tif r.buf == nil {\n\t\tif r.eof {\n\t\t\treturn 0, io.EOF\n\t\t}\n\n\t\t// Buffer empty. Get next segment.\n\n\t\tr.mu.Lock()\n\t\tif r.closed {\n\t\t\tr.mu.Unlock()\n\t\t\treturn 0, errors.New(\"side input closed\")\n\t\t}\n\t\tlocalChannel := r.ch\n\t\tr.mu.Unlock()\n\n\t\treq := &fnpb.StateRequest{\n\t\t\t// Id: set by StateChannel\n\t\t\tInstructionId: string(r.instID),\n\t\t\tStateKey:      r.key,\n\t\t\tRequest: &fnpb.StateRequest_Get{\n\t\t\t\tGet: &fnpb.StateGetRequest{\n\t\t\t\t\tContinuationToken: r.token,\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tresp, err := localChannel.Send(req)\n\t\tif err != nil {\n\t\t\tr.Close()\n\t\t\treturn 0, err","sourceCodeStart":469,"sourceCodeEnd":505,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/harness/statemgr.go#L469-L505","documentation":"The harness side-input reader fetches segments from the state manager over a channel. When the buffer is empty and the reader has been closed (r.closed), Read returns this error instead of issuing another state request, since no further data can ever arrive.","triggerScenarios":"Calling Read on a sideInputReader after its Close/cleanup ran, or a Downstream read continuing after the reader was closed due to bundle teardown or an upstream abort.","commonSituations":"Bundle cancellation mid-iteration of a side input; exec code retaining a side-input reader across node teardown; harness shutdown while a DoFn is still iterating the side input.","solutions":["Stop iterating the side input when the reader is closed; propagate cancellation from bundle teardown.","Ensure exec nodes do not outlive their side-input readers (release/cancel readers on teardown).","If reads can legitimately race with close, guard with a closed check or treat the error as termination."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if reader.Closed() { return io.EOF /* or stop iteration */ }","typeGuard":"func readable(r *sideInputReader) bool { return r != nil && !r.closed }","tryCatchPattern":"n, err := reader.Read(ctx, key)\nif err != nil && strings.Contains(err.Error(), \"side input closed\") {\n    return errStopIteration // bundle is tearing down; stop reading\n}","preventionTips":["Bind side-input iteration to bundle context cancellation","Never retain side-input readers beyond node/bundle teardown","Check reader liveness before each segment request in long-running iterations"],"tags":["go","apache-beam","harness","side-input","statemgr"],"backgroundTag":"invalid-state-transition","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}