Skip to content
This repository was archived by the owner on Oct 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 50 additions & 2 deletions packages/rivetkit/src/manager/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ function addManagerRoutes(
path: "/actors",
request: {
query: z.object({
name: z.string(),
name: z.string().optional(),
actor_ids: z.string().optional(),
key: z.string().optional(),
}),
Expand All @@ -282,6 +282,37 @@ function addManagerRoutes(

const actors: ActorOutput[] = [];

// Validate: cannot provide both actor_ids and (name or key)
if (actorIdsParsed && (name || key)) {
return c.json(
{
error:
"Cannot provide both actor_ids and (name + key). Use either actor_ids or (name + key).",
},
400,
);
}

// Validate: when key is provided, name must also be provided
if (key && !name) {
return c.json(
{
error: "When providing 'key', 'name' must also be provided.",
},
400,
);
}

// Validate: must provide either actor_ids or (name + key)
if (!actorIdsParsed && !key) {
return c.json(
{
error: "Must provide either 'actor_ids' or both 'name' and 'key'.",
},
400,
);
}

if (actorIdsParsed) {
if (actorIdsParsed.length > 32) {
return c.json(
Expand All @@ -298,8 +329,10 @@ function addManagerRoutes(
});
}

// Fetch actors by ID
for (const actorId of actorIdsParsed) {
if (name) {
// If name is provided, use it directly
const actorOutput = await managerDriver.getForId({
c,
name,
Expand All @@ -308,12 +341,27 @@ function addManagerRoutes(
if (actorOutput) {
actors.push(actorOutput);
}
} else {
// If no name is provided, try all registered actor types
// Actor IDs are globally unique, so we'll find it in one of them
for (const actorName of Object.keys(registryConfig.use)) {
const actorOutput = await managerDriver.getForId({
c,
name: actorName,
actorId,
});
if (actorOutput) {
actors.push(actorOutput);
break; // Found the actor, no need to check other names
}
}
}
}
} else if (key) {
// At this point, name is guaranteed to be defined due to validation above
const actorOutput = await managerDriver.getWithKey({
c,
name,
name: name!,
key: [key], // Convert string to ActorKey array
});
if (actorOutput) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export async function getActor(
return apiCall<never, ActorsListResponse>(
config,
"GET",
`/actors?name=${name}&actor_ids=${encodeURIComponent(actorId)}`,
`/actors?actor_ids=${encodeURIComponent(actorId)}`,
);
}

Expand Down
3 changes: 1 addition & 2 deletions packages/rivetkit/src/remote-manager-driver/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ export class RemoteManagerDriver implements ManagerDriver {
if (!runConfig.disableHealthCheck) {
this.#metadataPromise = this.#performMetadataCheck(runConfig);
this.#metadataPromise.catch((error) => {
// TODO: Promot to error after metadata endpoint merged on prod
logger().info({
logger().error({
msg: "metadata check failed",
error: error instanceof Error ? error.message : String(error),
});
Expand Down
Loading