Limits and errors

Limits

The limits an app's calls are held to. A running app can read the numbers of the Tinylib it's running on from platform.limits.

LimitValueDescription
data.keyLength128 characters
data.valueBytes64 KBOne value, as JSON. In a private app, measured before encryption.
data.keysPerApp500
data.appBytes1 MBAll of a user's values in the app added together, each measured as for valueBytes.
notifications.titleLength80 characters
notifications.bodyLength300 characters
notifications.perDay20Scheduled in any 24 hours.
notifications.waiting50Scheduled and not yet sent.
notifications.aheadDays30 daysHow far ahead at can be.
shared.keys32
shared.valueBytes4 KBOne value, as JSON.
shared.bytes16384All of the values added together, each measured as for valueBytes.
shared.page50The most people one list returns.
shared.pageDefault25The people one list returns when it names no limit.
rooms.maxMembers6The most members a room can have. server.js's size can be smaller.
rooms.perPerson20Rooms of one app a person can be in at once: rooms they haven't left that haven't ended. Past it, createRoom and a join are refused with too_many_rooms. host.rooms() answers at most this many rooms: every one that hasn't ended, then ended ones.
rooms.openInvites20Invites one person has open in one app's rooms at once, from the sheet and by id. An invite past it is refused with too_many_invites.
rooms.stateBytes128 KBA room's state from server.js, as JSON. A change that goes over it is refused with too_big.
rooms.viewBytes64 KBWhat view returns for one member, as JSON. A change that goes over it is refused with too_big.
rooms.argsBytes16 KBThe arguments of one act, as JSON.
rooms.optionsBytes16 KBThe options host.createRoom gets, as JSON.
rooms.memberEntries32Entries in a room's members, people who left included. A join past it is refused with full.
rooms.idleDays7 daysWhen server.js exports turn, a room that stores no change for this long runs left for each member turn names, and ends when turn then names nobody.
rooms.callsPerSecond20room.act calls one member makes in one room each second. A call past it is refused with too_many_calls.
rooms.endedDays30 daysHow long an ended room's data stays readable before it's deleted.
rooms.retryAfterSeconds60How long a room's change waits after an ask before the Worker's every-minute cron asks again (record 0030).
rooms.retryBatch50Rooms the Worker's every-minute cron asks to take their changes in one run, the longest waiting first (record 0030).
server.cpuMs0.05 secondsCPU time one call into server.js can use.
server.waitMs10 secondsTime one call into server.js can take, waiting included.
server.messageLength300 charactersThe message ctx.refuse gives. Its code is held to data.keyLength.
server.logLinesPerCall20Lines of console output kept from one call.
server.logLineLength500 charactersCharacters kept of one line of console output.
private.unlockMinutes15 minutesTinylib closes a private app this long after unlocking it.
calls.timeoutMs15 secondsA call Tinylib hasn't answered by then rejects with timeout, except calls that wait on the user, act and leave. The room refuses an act it hasn't finished by then with failed.

Errors

ErrorCode

type ErrorCode = 
  | "outside_host"
  | "timeout"
  | "failed"
  | "signed_out"
  | "offline"
  | "invalid_key"
  | "invalid_value"
  | "value_too_large"
  | "too_many_keys"
  | "too_much_data"
  | "private_app"
  | "unreadable"
  | "invalid_notification"
  | "denied"
  | "too_many_notifications"
  | "too_many_waiting"
  | "too_many_rooms"
  | "too_many_invites"
  | "not_member"
  | "needs_tap"
  | "too_many_calls"
  | "too_big"
  | "refused"
  | "not_your_turn"
  | "not_started"
  | "too_few"
  | "unknown_action"
  | "not_removable"
  | "ended"
  | "full"
  | "no_invite"
  | "not_joinable";

The reasons a call can reject.

CodeFromWhen
outside_hostevery callThe page isn't running inside Tinylib.
timeoutevery call but act, leave and those that wait on the userTinylib didn't answer within limits.calls.timeoutMs.
failedevery callSomething went wrong on Tinylib's side, or server.js threw or took too long. Try again.
signed_outcreateRoom, rooms(), a room's calls, notifications.schedule, cancel, listNobody is signed in. After a click or a tap, Tinylib asks the user to sign in first, and the call rejects when they don't; signing in opens the app again.
offlinecreateRoom, rooms(), a room's calls, notifications.schedule, cancel, list, friends.list, public.listNo connection.
invalid_keydata, friends, publicThe key is empty or over the length limit.
invalid_valueevery set, createRoom, actThe value can't be turned into JSON.
value_too_largeevery setThe value is over the limit for its store.
too_many_keysevery setThe key is new and the store already holds the limit.
too_much_dataevery setThe values in the store would add up to more than the limit.
private_appfriends, publicThe app is private, and has no audience stores.
unreadabledata.get, data.getAllA private app's value won't decrypt.
invalid_notificationnotifications.scheduleA field is missing or over its limit, or at isn't a time.
deniednotifications.scheduleThe user said no to this app's notifications. The switch on the app's page changes that.
too_many_notificationsnotifications.scheduleThe daily limit is used up.
too_many_waitingnotifications.scheduleThe limit on notifications waiting to be sent is reached.
too_many_roomscreateRoomThe user is in limits.rooms.perPerson rooms in this app that haven't ended.
too_bigcreateRoom, actoptions or args is over its limit, or the action would take the state or a view over its limit. See limits.rooms.
refusedactserver.js called ctx.refuse. The message is its sentence.
not_your_turnactturn doesn't name the user.
not_startedactThe game hasn't started.
too_fewstartFewer than players.min are in the game.
unknown_actionact, startserver.js has no action by that name, or start was called in a shared room.
not_removableactThe action called ctx.remove with the user's own id, a member who left, someone never in the room, or an id it already removed.
not_membera room's callsThe user left the room, or it was deleted.
endedact, start, invite, an invite's joinThe room has ended, so nothing can change it.
fullinvite, an invite's joinEvery place in the room is taken, or the game has started.
too_many_invitesinviteThe user would have more than limits.rooms.openInvites invites open in this app.
no_invitean invite's joinThe invite stopped: its sender left, or the user declined it on another device.
not_joinablean invite's joinserver.js's joinable turned the user away, or a block keeps them out.
needs_tapinvite, an invite's join and decline, notifications.scheduleThe call didn't follow a click or a tap. For notifications.schedule, also when the user closed the sheet without answering.
too_many_callsact, startThe user acted in the room more than limits.rooms.callsPerSecond times this second.

CallError

What a refused call rejects with. Branch on code. For each of Tinylib's codes, the message is the sentence a person reads, and a page can show it as it is; its wording can change. When Tinylib knows more about what went wrong, it writes that to the console. refused carries the sentence server.js passed to ctx.refuse.

Example

try {
  await host.data.set('big', 'x'.repeat(70 * 1024))
} catch (error) {
  if (error.code === 'value_too_large') splitIntoPages()
}

Extends

  • Error

Properties

PropertyType
codeErrorCode | string & object