wavetermdev/waveterm · error

error decoding input data: %w

Error message

error decoding input data: %w

What it means

HandleInput decodes the base64-encoded InputData64 field from a job-input RPC and writes the bytes to the job's PTY. This error is returned when base64.StdEncoding.Decode fails, meaning the client sent data that is not valid standard base64. It wraps the underlying decoding error (e.g. illegal base64 data at input byte N).

Source

Thrown at pkg/jobmanager/jobcmd.go:192

	jm.lock.Lock()
	defer jm.lock.Unlock()
	return jm.setTermSize_withlock(termSize)
}

// TODO set up a single input handler loop + queue so we dont need to hold the lock but still get synchronized in-order execution
func (jm *JobCmd) HandleInput(data wshrpc.CommandJobInputData) error {
	jm.lock.Lock()
	defer jm.lock.Unlock()

	if jm.cmd == nil || jm.cmdPty == nil {
		return fmt.Errorf("no active process")
	}

	if len(data.InputData64) > 0 {
		inputBuf := make([]byte, base64.StdEncoding.DecodedLen(len(data.InputData64)))
		nw, err := base64.StdEncoding.Decode(inputBuf, []byte(data.InputData64))
		if err != nil {
			return fmt.Errorf("error decoding input data: %w", err)
		}
		_, err = jm.cmdPty.Write(inputBuf[:nw])
		if err != nil {
			return fmt.Errorf("error writing to pty: %w", err)
		}
	}

	if data.SigName != "" {
		sig := unixutil.ParseSignal(data.SigName)
		if sig != nil && jm.cmd.Process != nil {
			err := jm.cmd.Process.Signal(sig)
			if err != nil {
				return fmt.Errorf("error sending signal: %w", err)
			}
		}
	}

	if data.TermSize != nil {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Re-encode the payload on the client with base64.StdEncoding.EncodeToString before sending
  2. If the payload uses URL-safe base64, convert with strings.NewReplacer("-","+","_","/") and re-add padding before sending
  3. Log the InputData64 value and check the wrapped error's input byte offset to find the first corrupt character
  4. Upgrade/fix the client library so it matches the server's standard encoding expectation

Example fix

// before
inputData.InputData64 = base64.URLEncoding.EncodeToString(buf)
// after
inputData.InputData64 = base64.StdEncoding.EncodeToString(buf)
Defensive patterns

Strategy: validation

Validate before calling

func isValidStdBase64(s string) bool {
    if len(s) == 0 || len(s)%4 != 0 {
        return false
    }
    _, err := base64.StdEncoding.DecodeString(s)
    return err == nil
}
if !isValidStdBase64(inputData.InputData64) {
    // fix encoding before calling the input RPC
}

Try / catch

if err := handleInput(data); err != nil {
    var b64Err base64.CorruptInputError
    if errors.As(err, &b64Err) {
        // re-encode payload with base64.StdEncoding and retry once
    }
}

Prevention

When it happens

Trigger: Calling the job input RPC (HandleInput via the wsh job input path) with InputData64 containing characters outside the standard base64 alphabet, incorrect padding, or an empty string with whitespace/URL-safe -_ characters instead of +/.

Common situations: A client encodes input with base64.URLEncoding or RawStdEncoding instead of base64.StdEncoding; manual string construction that corrupts padding; a middleware or log pipeline mangles the '+' character into spaces in form/query encoding.

Related errors


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