wavetermdev/waveterm · error

failed to attach job to block: %w

Error message

failed to attach job to block: %w

What it means

If params.BlockId is set, StartJob attaches the new job to that block via AttachJobToBlock (which also sends status); failure is wrapped with this message. It means the target block could not be found, loaded, or updated to reference the job.

Source

Thrown at pkg/jobcontroller/jobcontroller.go:673

		CmdArgs:          params.Args,
		CmdEnv:           params.Env,
		CmdTermSize:      *params.TermSize,
		JobAuthToken:     jobAuthToken,
		JobManagerStatus: JobManagerStatus_Init,
		AttachedBlockId:  params.BlockId,
		WaveVersion:      wavebase.WaveVersion,
		Meta:             make(waveobj.MetaMapType),
	}

	err = wstore.DBInsert(ctx, job)
	if err != nil {
		return "", fmt.Errorf("failed to create job in database: %w", err)
	}
	if params.BlockId != "" {
		// AttachJobToBlock will send status
		err = AttachJobToBlock(ctx, jobId, params.BlockId)
		if err != nil {
			return "", fmt.Errorf("failed to attach job to block: %w", err)
		}
	}
	bareRpc := wshclient.GetBareRpcClient()
	broker := bareRpc.StreamBroker
	readerRouteId := wshclient.GetBareRpcClientRouteId()
	writerRouteId := wshutil.MakeJobRouteId(jobId)
	reader, streamMeta := broker.CreateStreamReader(readerRouteId, writerRouteId, DefaultStreamRwnd)
	jobStreamIds.Set(jobId, streamMeta.Id)

	fileOpts := wshrpc.FileOpts{
		MaxSize:  10 * 1024 * 1024,
		Circular: true,
	}
	err = filestore.WFS.MakeFile(ctx, jobId, JobOutputFileName, wshrpc.FileMeta{}, fileOpts)
	if err != nil {
		return "", fmt.Errorf("failed to create WaveFS file: %w", err)
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Verify the BlockId refers to an existing, open block before calling StartJob.
  2. Retry with a fresh BlockId obtained from the current UI state.
  3. If the job does not need a terminal block, omit BlockId entirely (it is optional).

Example fix

// before
jobId, err := jobcontroller.StartJob(ctx, jobcontroller.StartJobParams{BlockId: staleBlockId, ...})
// after
block, err := wstore.DBGet[*waveobj.Block](ctx, staleBlockId)
if err != nil { staleBlockId = "" } // start without attaching
jobId, err := jobcontroller.StartJob(ctx, jobcontroller.StartJobParams{BlockId: staleBlockId, ...})
Defensive patterns

Strategy: validation

Validate before calling

if params.BlockId != "" {
    if _, err := wstore.DBGet[*waveobj.Block](ctx, params.BlockId); err != nil {
        params.BlockId = "" // block gone; start job unattached instead of failing
    }
}

Prevention

When it happens

Trigger: Calling StartJob with a BlockId that does not exist, was deleted, or whose backing objects cannot be read/updated in wstore.

Common situations: Stale BlockId captured before the block/tab/window was closed, race where the UI closed the block while the job was starting, invalid BlockId passed programmatically.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/07b5a746c1e3d873. Report an issue: GitHub.