cube-js/cube · error · PostgresError

Unable to detect type for field "${f.name}" with dataTypeID:

Error message

Unable to detect type for field "${f.name}" with dataTypeID: ${f.dataTypeID}

What it means

PostgresDriver.mapFields maps pg result field OIDs (dataTypeID) to Cube types via getPostgresTypeForField. When the OID is unknown to the driver's type map, it cannot determine the column type and throws a PostgresError naming the field and OID.

Source

Thrown at packages/cubejs-postgres-driver/src/PostgresDriver.ts:357

  }

  protected async prepareConnection(
    conn: PgClient,
    options: { executionTimeout: number } = {
      executionTimeout: this.config.executionTimeout ? <number>(this.config.executionTimeout) * 1000 : 600000
    }
  ) {
    await conn.query(`SET TIME ZONE '${this.config.storeTimezone || 'UTC'}'`);
    await conn.query(`SET statement_timeout TO ${options.executionTimeout}`);

    await this.loadUserDefinedTypes(conn);
  }

  protected mapFields(fields: FieldDef[]) {
    return fields.map((f) => {
      const postgresType = this.getPostgresTypeForField(f.dataTypeID);
      if (!postgresType) {
        throw new PostgresError(
          `Unable to detect type for field "${f.name}" with dataTypeID: ${f.dataTypeID}`
        );
      }

      return ({
        name: f.name,
        type: this.toGenericType(postgresType)
      });
    });
  }

  public async stream(
    query: string,
    values: unknown[],
    { highWaterMark }: StreamOptions
  ): Promise<StreamTableDataWithTypes> {
    PostgresDriver.checkValuesLimit(values);

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Cast the offending column to a standard type in the SQL: `col::text` (or ::int8, ::float8, etc.).
  2. Add the missing OID mapping if extending the driver (getPostgresTypeForField map).
  3. Update the data model so the member uses a base type rather than a custom type.
  4. Check driver/Postgres version mismatch — new built-in types may be unknown to older pg OIDs handled by the driver.

Example fix

// before
SELECT status FROM orders; -- status is a custom enum, dataTypeID unmapped
// after
SELECT status::text AS status FROM orders;
Defensive patterns

Strategy: validation

Validate before calling

// ensure selected columns are cast to base types
const KNOWN_OIDS = new Set([16, 20, 21, 23, 25, 700, 701, 1043, 1082, 1114, 1184, 1700]);
for (const f of fields) {
  if (!KNOWN_OIDS.has(f.dataTypeID)) console.warn(`Cast ${f.name} (OID ${f.dataTypeID}) to a base type`);
}

Type guard

function hasKnownType(f: FieldDef): boolean {
  return !!driver.getPostgresTypeForField(f.dataTypeID); // or check OID map
}

Try / catch

try {
  const res = await driver.downloadQueryResults(query);
} catch (e) {
  if (e.message.includes('Unable to detect type for field')) {
    console.error(`Add a cast (::text, ::int8, ...) for ${e.message.match(/field "(.*?)"/)?.[1]}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: `stream` or `downloadQueryResults` returns result fields whose dataTypeID is not in the driver's OID→type map — typically custom/composite/enum types or rarely used native types.

Common situations: Selecting custom enum or user-defined types in the query; Postgres extension types (e.g., hstore, geometry via older drivers); casting omissions in generated SQL after schema changes.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/a00c85f5bf16a603. Report an issue: GitHub.