Skip to main content
encodeAgentName(name): string
Encode a routing name into the actor id that addresses its instance. An actor id is not free-form. It is a path segment on every call to the instance, it is folded into the persistent records the instance owns, and it names the instance’s timers — and only ASCII letters, digits, -, _, and . survive all three. An id built from anything else is not merely ugly: it cannot be addressed, and the instance never activates. Names customers actually route on are not confined to that set — a phone number (+15550100), an email address, a composite key, a name with accents or emoji. This encoder maps any such name onto the addressable set, and back again:
The scheme Each run of characters outside the addressable set becomes : + the lowercase hex of that run’s UTF-8 bytes + :. Characters inside the set are written through untouched. : itself is never written through — it is always escaped (: → :3a:) — which is what makes an escape impossible to confuse with an ordinary name and the encoding reversible by decodeAgentName. Two names therefore never share an id: the id says exactly which characters were escaped, so it decodes back to one name and one name only. How long a name may be The limit is on the ID once URL-escaped, not on the name: an actor id may occupy at most MAX_ESCAPED_ACTOR_ID_LENGTH characters escaped, and a name whose id would be longer is refused here rather than handed back as an id the platform cannot keep an instance under. So how many characters of name fit depends on which characters they are, because an escape is longer than what it replaces — two hex digits per UTF-8 byte, plus the two : bracketing each run, which cost three apiece once URL-escaped:
An all-ASCII name (letters, digits, -, _, .) gets the full 225, since it passes through unchanged and has nothing to escape. Everything else costs more: 4 characters per accented Latin letter (54 of them fit), 6 per three-byte character such as ☕ or most CJK (36 fit), and 8 per emoji or other astral character (27 fit), with a further 6 for each separate run of them. Budget for the characters your names actually use, use escapedActorIdLength when you need the exact number, and prefer catching the throw over assuming a name fits. This encoding is part of an actor’s identity, and is frozen The id an instance is first addressed by is the id its persistent state, its timers, and every later request are filed under. Changing how a name encodes re-points that name at a different, empty instance and orphans everything the old one held. Treat the mapping as fixed for the lifetime of the deployment: the same name must always yield the same id. It will not be changed under you, and you should not re-derive it — call this function instead. That is also why mountAgents applies it to every name it resolves: a mounted agent needs no encoding code, and a hand-written front door that addresses the SAME instances stays in step by calling this rather than writing the rule out again. Names already inside the addressable set pass through byte-for-byte, so adopting the encoder never re-points an instance that was already reachable. Two things to get right Takes the RAW name, exactly once. Encoding an already-encoded name escapes its : signs (":2b:15550100" → ":3a:2b:3a:15550100") and addresses a different instance — pass the name as the caller wrote it, not a value read out of a URL path without decoding it first. Letter case is significant: Alice and alice are different names and different instances. Lowercase your names before you route on them if you mean them to be the same. Parameters Returns string The actor id for that name, built only from ASCII letters, digits, -, _, ., and :. Throws TypeError when the name has no faithful id and encoding it would hand back one that cannot be addressed: an empty name, one whose id would occupy more than MAX_ESCAPED_ACTOR_ID_LENGTH characters once escaped (which a name of more than that many characters always does), or one containing an unpaired surrogate. The message names the offending input and the limit it missed.