temporalio/temporal · error
link type contains invalid char (valid chars: alphanumeric,
Error message
link type contains invalid char (valid chars: alphanumeric, '_', '.', '/')
What it means
validateLinkType rejects link type strings containing characters outside [a-zA-Z0-9_.\/] because link types appear in headers and routing keys where arbitrary characters are unsafe. encodeLink and decodeLink call it, so any Link whose Type contains spaces, hyphens, colons, or unicode characters fails with this error.
Source
Thrown at common/nexus/nexusrpc/api.go:248
func validateLinkURL(value *url.URL) error {
if value == nil || value.String() == "" {
return errors.New("url is empty")
}
_, err := url.ParseQuery(value.RawQuery)
if err != nil {
return fmt.Errorf("url query not percent-encoded: %s", value)
}
return nil
}
func validateLinkType(value string) error {
if len(value) == 0 {
return errors.New("link type is empty")
}
for _, c := range value {
if (c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '_' && c != '.' && c != '/' {
return errors.New("link type contains invalid char (valid chars: alphanumeric, '_', '.', '/')")
}
}
return nil
}
var durationRegexp = regexp.MustCompile(`^(\d+(?:\.\d+)?)(ms|s|m)$`)
func ParseDuration(value string) (time.Duration, error) {
m := durationRegexp.FindStringSubmatch(value)
if len(m) == 0 {
return 0, fmt.Errorf("invalid duration: %q", value)
}
v, err := strconv.ParseFloat(m[1], 64)
if err != nil {
return 0, err
}
switch m[2] {View on GitHub (pinned to bde624efd1)
Solutions
- Rewrite the link Type using only alphanumerics, '_', '.', or '/' (e.g. replace '-' with '_' or '.')
- Sanitize/normalize the type string at the point where the link is constructed
- Validate user- or config-supplied type names with the same character set before creating links
Example fix
// before link.Type = "my-service.Callback" // after link.Type = "my_service.Callback"
Defensive patterns
Strategy: validation
Validate before calling
var linkTypeRe = regexp.MustCompile(`^[a-zA-Z0-9_./]+$`)
func validLinkType(t string) bool { return linkTypeRe.MatchString(t) } Type guard
if !linkTypeRe.MatchString(link.Type) { return fmt.Errorf("link type %q has invalid chars", link.Type) } Try / catch
if err := encodeLink(link); err != nil {
var invalid = strings.Contains(err.Error(), "invalid char")
// sanitize or reject
} Prevention
- Sanitize externally supplied type names (replace '-', ':', spaces) before constructing links
- Use '/' or '.' as separators instead of '-' or ':' in type names
- Add a lint/test asserting all link types in the codebase match the charset regex
When it happens
Trigger: Encoding or decoding a nexus Link whose Type contains an invalid character — e.g. Type set to 'my-service', 'com:example:Type', or any value with spaces or non-ASCII characters.
Common situations: Developers using hyphenated service names or colon-separated identifiers as link types; porting conventions from other systems that allow different separators; copy-pasted type names with trailing whitespace.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- link type is empty
- empty operation name
- empty operation token
- ErrInvalidOperationToken
- second value out of range: %v
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/158f725205358825.
Report an issue: GitHub.