wavetermdev/waveterm · error

JobId mismatch

Error message

JobId mismatch

What it means

The JWT is valid and carries MainServer=true, but the JobId embedded in the token does not match the JobId the job manager is running for. This prevents a token minted for one job from authenticating to another job's manager.

Source

Thrown at pkg/jobmanager/mainserverconn.go:83

	log.Printf("authenticateSelfToServer: successfully authenticated to server\n")
	return nil
}

func (msc *MainServerConn) AuthenticateToJobManagerCommand(ctx context.Context, data wshrpc.CommandAuthenticateToJobData) error {
	jobId, jobAuthToken := WshCmdJobManager.GetJobAuthInfo()

	claims, err := wavejwt.ValidateAndExtract(data.JobAccessToken)
	if err != nil {
		log.Printf("AuthenticateToJobManager: failed to validate token: %v\n", err)
		return fmt.Errorf("failed to validate token: %w", err)
	}
	if !claims.MainServer {
		log.Printf("AuthenticateToJobManager: MainServer claim not set\n")
		return fmt.Errorf("MainServer claim not set")
	}
	if claims.JobId != jobId {
		log.Printf("AuthenticateToJobManager: JobId mismatch: expected %s, got %s\n", jobId, claims.JobId)
		return fmt.Errorf("JobId mismatch")
	}
	msc.PeerAuthenticated.Store(true)
	log.Printf("AuthenticateToJobManager: authentication successful for JobId=%s\n", claims.JobId)

	err = msc.authenticateSelfToServer(jobAuthToken)
	if err != nil {
		msc.PeerAuthenticated.Store(false)
		return err
	}

	WshCmdJobManager.SetAttachedClient(msc)
	return nil
}

func (msc *MainServerConn) StartJobCommand(ctx context.Context, data wshrpc.CommandStartJobData) (*wshrpc.CommandStartJobRtnData, error) {
	log.Printf("StartJobCommand: received command=%s args=%v", data.Cmd, data.Args)
	if !msc.PeerAuthenticated.Load() {
		log.Printf("StartJobCommand: not authenticated")

View on GitHub (pinned to a4447c1563)

Solutions

  1. Regenerate the job access token for the correct jobId and retry authentication.
  2. Confirm the client is connecting to the intended job manager instance (check the jobId in logs: 'expected %s, got %s').
  3. If the job was recreated, refresh auth info via GetJobAuthInfo before authenticating.

Example fix

// before
authData.JobAccessToken = oldJobToken // minted for job-123
// after
jobId, _ := WshCmdJobManager.GetJobAuthInfo()
authData.JobAccessToken = issueJobToken(jobId) // token matches current job
Defensive patterns

Strategy: validation

Validate before calling

jobId, _ := WshCmdJobManager.GetJobAuthInfo()
// verify token jobId matches before authenticating
tokClaims, err := wavejwt.ValidateAndExtract(token)
if err == nil && tokClaims.JobId != jobId {
    return fmt.Errorf("token is for job %s, manager is %s", tokClaims.JobId, jobId)
}

Try / catch

if err := conn.AuthenticateToJobManagerCommand(ctx, authData); err != nil {
    if strings.Contains(err.Error(), "JobId mismatch") {
        authData.JobAccessToken = issueTokenForJob(currentJobId)
        err = conn.AuthenticateToJobManagerCommand(ctx, authData)
    }
    if err != nil { return err }
}

Prevention

When it happens

Trigger: AuthenticateToJobManagerCommand receives a token whose claims.JobId differs from the value returned by WshCmdJobManager.GetJobAuthInfo() — connecting with a token from a different/previous job.

Common situations: Reusing tokens across job restarts, mixing up jobIds when managing multiple jobs, stale tokens after a job was recreated with a new id.

Related errors


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