Tencent/WeKnora · error
sandbox binding session must not contain control characters
Error message
sandbox binding session must not contain control characters
What it means
Character-validation guard in SessionSandboxKey.Validate: fires when the SessionID of a tenant-scoped sandbox binding contains ASCII/Unicode control characters. Control characters in a session identifier could break binding serialization or enable injection into stored keys, so the key is rejected as unable to safely identify a tenant session.
Source
Thrown at internal/sandbox/session_binding.go:32
const SessionSandboxBindingVersion = 1
// SessionSandboxKey identifies one tenant-scoped persistent sandbox.
type SessionSandboxKey struct {
TenantID uint64
SessionID string
}
// Validate rejects keys that cannot identify a tenant session.
func (k SessionSandboxKey) Validate() error {
if k.TenantID == 0 || strings.TrimSpace(k.SessionID) == "" {
return errors.New("sandbox binding requires tenant and session")
}
if strings.ContainsAny(k.SessionID, "{}") {
return errors.New("sandbox binding session must not contain braces")
}
for _, r := range k.SessionID {
if unicode.IsControl(r) {
return errors.New("sandbox binding session must not contain control characters")
}
}
return nil
}
// SessionSandboxBinding records the remote sandbox assigned to a session.
type SessionSandboxBinding struct {
Version int `json:"version"`
Provider RemoteProvider `json:"provider,omitempty"`
TenantID uint64 `json:"tenant_id"`
SessionID string `json:"session_id"`
SandboxID string `json:"sandbox_id"`
TemplateID string `json:"template_id"`
CreatedAt time.Time `json:"created_at"`
// ConfigID is the sandbox config the sandbox was created from. It is what
// makes "every sandbox of this config" answerable from the binding store:
// the sandbox itself carries the same value in provider metadata, but aView on GitHub (pinned to 988cbb0330)
Solutions
- Trim and sanitize the session ID (strings.TrimSpace, strip non-printable runes) before building the key.
- Validate identifiers at the API boundary with an allowlist (alphanumeric, hyphen, underscore).
- Ensure generators/parsers produce printable IDs (bare hex UUIDs).
Example fix
// before
key := sandbox.SessionSandboxKey{TenantID: 7, SessionID: headerValue} // may contain \n
// after
clean := strings.Map(func(r rune) rune { if unicode.IsControl(r) { return -1 }; return r }, strings.TrimSpace(headerValue))
key := sandbox.SessionSandboxKey{TenantID: 7, SessionID: clean} Defensive patterns
Strategy: validation
Validate before calling
func sanitizeSessionID(id string) string {
return strings.Map(func(r rune) rune {
if unicode.IsControl(r) { return -1 }
return r
}, strings.TrimSpace(id))
} Type guard
func printableSessionID(id string) bool {
for _, r := range id {
if unicode.IsControl(r) { return false }
}
return true
} Try / catch
if err := key.Validate(); err != nil {
if strings.Contains(err.Error(), "control characters") {
key.SessionID = sanitizeSessionID(key.SessionID)
return key.Validate()
}
return err
} Prevention
- Trim header-derived values before use as IDs.
- Use an allowlist regex for acceptable ID characters.
- Log IDs with %q to spot hidden control chars during debugging.
When it happens
Trigger: Passing a SessionSandboxKey whose SessionID contains control runes (\n, \t, \x00, ...) to Validate, usually from raw header values, untrimmed input, or byte-level parsing mistakes.
Common situations: Session ID read from an HTTP header including a trailing newline; IDs split from a text blob retaining \r\n; accidental concatenation with NUL bytes.
Related errors
- sandbox binding session must not contain braces
- E2B timeout must be at least one second
- invalid sandbox type
- timeout cannot be negative
- memory limit cannot be negative
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/f4926f4927142a11.
Report an issue: GitHub.