wavetermdev/waveterm · error

failed to get job: %w

Error message

failed to get job: %w

What it means

The command looked up the Job record by JobId in wstore (DBMustGet) and the lookup failed — usually the job does not exist (or the DB read errored). The underlying wstore error is wrapped with %w, so inspecting the chain reveals whether it is a not-found error or a database failure.

Source

Thrown at pkg/wshutil/wshrouter_controlimpl.go:232

	return rtnData, nil
}

func (impl *WshRouterControlImpl) AuthenticateJobManagerVerifyCommand(ctx context.Context, data wshrpc.CommandAuthenticateJobManagerData) error {
	if !impl.Router.IsRootRouter() {
		return fmt.Errorf("authenticatejobmanagerverify can only be called on root router")
	}

	if data.JobId == "" {
		return fmt.Errorf("no jobid in authenticatejobmanager message")
	}
	if data.JobAuthToken == "" {
		return fmt.Errorf("no jobauthtoken in authenticatejobmanager message")
	}

	job, err := wstore.DBMustGet[*waveobj.Job](ctx, data.JobId)
	if err != nil {
		log.Printf("wshrouter authenticate-jobmanager-verify error jobid=%q: failed to get job: %v", data.JobId, err)
		return fmt.Errorf("failed to get job: %w", err)
	}

	if job.JobAuthToken != data.JobAuthToken {
		log.Printf("wshrouter authenticate-jobmanager-verify error jobid=%q: invalid jobauthtoken", data.JobId)
		return fmt.Errorf("invalid jobauthtoken")
	}

	log.Printf("wshrouter authenticate-jobmanager-verify success jobid=%q", data.JobId)
	return nil
}

func (impl *WshRouterControlImpl) AuthenticateJobManagerCommand(ctx context.Context, data wshrpc.CommandAuthenticateJobManagerData) error {
	handler := GetRpcResponseHandlerFromContext(ctx)
	if handler == nil {
		return fmt.Errorf("no response handler in context")
	}
	linkId := handler.GetIngressLinkId()
	if linkId == baseds.NoLinkId {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Check errors.Is/Unwrap on the error for a not-found result from wstore.DBMustGet.
  2. Verify the JobId exists in the wstore DB used by the root router (same WAVE datastore).
  3. Re-create the job and use the fresh job id for verification.
  4. If it is a DB error (not not-found), check datastore file permissions/integrity and wstore logs.

Example fix

// before
job, err := wstore.DBMustGet[*waveobj.Job](ctx, data.JobId)
if err != nil {
    return fmt.Errorf("failed to get job: %w", err)
}
// after
job, err := wstore.DBGet[*waveobj.Job](ctx, data.JobId)
if err != nil {
    if wstore.IsNotFound(err) {
        return fmt.Errorf("job %q not found: %w", data.JobId, err)
    }
    return fmt.Errorf("failed to get job: %w", err)
}
Defensive patterns

Strategy: try-catch

Type guard

func isNotFoundErr(err error) bool {
    return errors.Is(err, wstore.ErrNotFound) || strings.Contains(err.Error(), "not found")
}

Try / catch

err := verifyJobManager(ctx, data)
if err != nil {
    if isNotFoundErr(errors.Unwrap(err)) {
        // job record gone: recreate job and retry once with fresh id/token
        return recreateJobAndVerify(ctx)
    }
    return fmt.Errorf("job lookup failed: %w", err)
}

Prevention

When it happens

Trigger: Calling AuthenticateJobManagerVerify with a JobId that has no corresponding *waveobj.Job in the wstore DB — deleted job, wrong id, different database/environment, or an actual DB read error.

Common situations: Job-manager restarted against a different WAVE datastore path; job record expired/purged before verification; stale job id cached on the client; database permission/IO problems.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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