From 4d0819abd29a5ba911ebefd239e7872fd29f9828 Mon Sep 17 00:00:00 2001 From: gnzjgo Date: Mon, 23 Mar 2026 16:06:23 +0100 Subject: [PATCH 1/3] fix: show meaningful error messages instead of undefined on build/dev failures (#131) Amp-Thread-ID: https://ampcode.com/threads/T-019d1b0d-6dca-7013-a8f8-af75363aae7d Co-authored-by: Amp --- src/api/build.ts | 2 +- src/cli/index.ts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/api/build.ts b/src/api/build.ts index ecf5939..6897621 100644 --- a/src/api/build.ts +++ b/src/api/build.ts @@ -223,7 +223,7 @@ export async function buildToTinybird( if (body.errors && body.errors.length > 0) { return body.errors.map(e => { const prefix = e.filename ? `[${e.filename}] ` : ''; - return `${prefix}${e.error}`; + return `${prefix}${e.error ?? 'Unknown error'}`; }).join('\n'); } return body.error || `HTTP ${response.status}: ${response.statusText}`; diff --git a/src/cli/index.ts b/src/cli/index.ts index 368fef8..6ce2c85 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -541,6 +541,8 @@ function createCli(): Command { output.showBuildErrors(deploy.errors); } else if (result.error) { output.error(result.error); + } else { + output.error("Deploy failed (no error details available, run with TINYBIRD_DEBUG=1 for more info)"); } output.showDeployFailure(); process.exit(1); @@ -732,6 +734,8 @@ function createCli(): Command { output.showBuildErrors(deploy.errors); } else if (result.error) { output.error(result.error); + } else { + output.error("Build failed (no error details available, run with TINYBIRD_DEBUG=1 for more info)"); } output.showBuildFailure(true); return; From d6b1dd717d7c66667a317583696179b4ba484a3f Mon Sep 17 00:00:00 2001 From: gnzjgo Date: Mon, 23 Mar 2026 16:06:41 +0100 Subject: [PATCH 2/3] feat: add ingestBatch method to datasource accessors (#132) Amp-Thread-ID: https://ampcode.com/threads/T-019d1b0d-6dca-7013-a8f8-af75363aae7d Co-authored-by: Amp --- src/schema/project.test.ts | 6 ++++-- src/schema/project.ts | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/schema/project.test.ts b/src/schema/project.test.ts index dc17874..f8deba6 100644 --- a/src/schema/project.test.ts +++ b/src/schema/project.test.ts @@ -94,7 +94,7 @@ describe("Project Schema", () => { expect((project.tinybird as unknown as Record).pipes).toBeUndefined(); }); - it("creates datasource accessors with ingest/append/replace/delete/truncate methods", () => { + it("creates datasource accessors with ingest/ingestBatch/append/replace/delete/truncate methods", () => { const events = defineDatasource("events", { schema: { timestamp: t.dateTime() }, }); @@ -105,6 +105,7 @@ describe("Project Schema", () => { expect(project.tinybird.events).toBeDefined(); expect(typeof project.tinybird.events.ingest).toBe("function"); + expect(typeof project.tinybird.events.ingestBatch).toBe("function"); expect(typeof project.tinybird.events.append).toBe("function"); expect(typeof project.tinybird.events.replace).toBe("function"); expect(typeof project.tinybird.events.delete).toBe("function"); @@ -316,7 +317,7 @@ describe("Project Schema", () => { expect((client as unknown as Record).pipes).toBeUndefined(); }); - it("creates datasource accessors with ingest/append/replace/delete/truncate methods", () => { + it("creates datasource accessors with ingest/ingestBatch/append/replace/delete/truncate methods", () => { const events = defineDatasource("events", { schema: { id: t.string() }, }); @@ -328,6 +329,7 @@ describe("Project Schema", () => { expect(client.events).toBeDefined(); expect(typeof client.events.ingest).toBe("function"); + expect(typeof client.events.ingestBatch).toBe("function"); expect(typeof client.events.append).toBe("function"); expect(typeof client.events.replace).toBe("function"); expect(typeof client.events.delete).toBe("function"); diff --git a/src/schema/project.ts b/src/schema/project.ts index 540d547..0fa72e5 100644 --- a/src/schema/project.ts +++ b/src/schema/project.ts @@ -14,6 +14,7 @@ import type { DatasourcesNamespace, DeleteOptions, DeleteResult, + IngestOptions, IngestResult, QueryOptions, QueryResult, @@ -69,6 +70,8 @@ type PipeEntityAccessors = { type DatasourceAccessor> = { /** Ingest a single event row */ ingest(event: InferRow): Promise; + /** Ingest multiple event rows in a batch */ + ingestBatch(events: InferRow[], options?: IngestOptions): Promise; /** Append data from a URL or file */ append(options: AppendOptions): Promise; /** Replace datasource content from a URL or file */ @@ -358,6 +361,10 @@ export const Tinybird: TinybirdConstructor = class Tinybird< const client = await this.#getClient(); return client.datasources.ingest(tinybirdName, event as Record); }, + ingestBatch: async (events: unknown[], options: IngestOptions = {}) => { + const client = await this.#getClient(); + return client.datasources.ingestBatch(tinybirdName, events as Record[], options); + }, append: async (options: AppendOptions) => { const client = await this.#getClient(); return client.datasources.append(tinybirdName, options); From fe8121e59b7580974e3407b8746eb29ea524f14d Mon Sep 17 00:00:00 2001 From: gnzjgo Date: Mon, 23 Mar 2026 17:37:19 +0100 Subject: [PATCH 3/3] fix: use client.ingestBatch instead of client.datasources.ingestBatch Amp-Thread-ID: https://ampcode.com/threads/T-019d1b0d-6dca-7013-a8f8-af75363aae7d Co-authored-by: Amp --- src/schema/project.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schema/project.ts b/src/schema/project.ts index 0fa72e5..994ff33 100644 --- a/src/schema/project.ts +++ b/src/schema/project.ts @@ -363,7 +363,7 @@ export const Tinybird: TinybirdConstructor = class Tinybird< }, ingestBatch: async (events: unknown[], options: IngestOptions = {}) => { const client = await this.#getClient(); - return client.datasources.ingestBatch(tinybirdName, events as Record[], options); + return client.ingestBatch(tinybirdName, events as Record[], options); }, append: async (options: AppendOptions) => { const client = await this.#getClient();