Summary
When an API Group's shared variable is bound to Authenticated User → JWT Token (i.e. an FFAuthVariable.JWT_TOKEN value source) and that variable is referenced inside a header via the [var] placeholder syntax, FlutterFlow's codegen produces an unresolvable Dart reference in lib/backend/api_requests/api_calls.dart.
The generated function falls back to a top-level identifier currentJwtToken (defined in lib/auth/firebase_auth/auth_util.dart), but api_calls.dart does not import auth_util.dart, so the build fails with:
lib/backend/api_requests/api_calls.dart:61:15: Error: Undefined name 'currentJwtToken'.
token ??= currentJwtToken!;
^^^^^^^^^^^^^^^
lib/backend/api_requests/api_calls.dart:78:15: Error: The getter 'currentJwtToken' isn't defined for the type 'MeetingSummaryCall'.
token ??= currentJwtToken!;
^^^^^^^^^^^^^^^
Example Generated code
// Top of lib/backend/api_requests/api_calls.dart — note: NO auth_util import
import 'dart:convert';
import 'dart:typed_data';
import '../schema/structs/index.dart';
import 'package:flutter/foundation.dart';
import '/flutter_flow/flutter_flow_util.dart';
import 'api_manager.dart';
// ...
class BuildshipSummaryGroup {
static String getBaseUrl({
String? token,
}) {
token ??= currentJwtToken!; // <-- unresolved
return 'https://4tgke4.buildship.run';
}
static Map<String, String> headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer [token]',
};
}
class MeetingSummaryCall {
Future<ApiCallResponse> call({
String? title = '',
String? points = '',
String? token,
}) async {
token ??= currentJwtToken!; // <-- unresolved
final baseUrl = BuildshipSummaryGroup.getBaseUrl(token: token);
// ...
}
}
flutter_flow_util.dart does not re-export auth_util.dart, and no other imported file in this file's import set transitively exposes currentJwtToken. Comparing against a working FF project on disk (one whose api_calls.dart was authored via the editor flow), the working file does not contain the token ??= currentJwtToken! fallback at all — its callers pass the token explicitly from page-widget code (which does import auth_util). The fallback emission is the difference, and it's only reachable when the auth-bound shared variable shape is set up in a particular way.
Repro steps
- New FlutterFlow project with Firebase Auth configured (email provider; sign-in/home pages set).
- Create a new API Group (e.g.
BuildshipSummary) with base URL https://example.com.
- Add a Group Variable named
token, type String. Value Source → Authenticated User → JWT Token.
- Add an endpoint (e.g. POST
/foo) on the group.
- On the group's Headers, add
Authorization: Bearer [token].
- Add a body (any shape).
- Reference the endpoint from anywhere in the app and run the project (
flutter run or any platform target).
Expected
api_calls.dart either:
- imports
'/auth/firebase_auth/auth_util.dart'; so the currentJwtToken reference resolves, or
- omits the
token ??= currentJwtToken! fallback entirely (matching the working pattern where the page-widget caller passes token: currentJwtToken from a context that already imports auth_util).
Actual
The fallback line is emitted in api_calls.dart without the corresponding import, so the build fails immediately with Undefined name 'currentJwtToken'.
Environment
- FlutterFlow project ID:
meeting-recall-bodg0v
- Auth-bound API group:
BuildshipSummary
- Endpoint:
MeetingSummary
- Authoring path: project state was constructed via the FlutterFlow AI DSL SDK (
flutterflow_ai); the same shape can presumably be built in the visual editor by following the repro steps above. If the visual editor produces a different proto shape that avoids this codegen path, that asymmetry between editor-authored and DSL-authored projects would itself be worth investigating.
- Built target: iOS (debug) on iPhone 17 Pro simulator.
Bug Code
IT4wi/Hl389Nobhe+KXydfowiiMXMjsma+cvjMJheCs9f5CvOpYUec/6PxBCZ8Pkd2NYOVqmp14E0sL6htjtFu0BFyeBf6ZD1ahMFjzMJD+uRYuTF7mZOHFAM9ljCFeB5LWFgyZAIshZcVoa3WDzJd6ucBPdGIzTDGo8Sq/LZO4=
Summary
When an API Group's shared variable is bound to Authenticated User → JWT Token (i.e. an
FFAuthVariable.JWT_TOKENvalue source) and that variable is referenced inside a header via the[var]placeholder syntax, FlutterFlow's codegen produces an unresolvable Dart reference inlib/backend/api_requests/api_calls.dart.The generated function falls back to a top-level identifier
currentJwtToken(defined inlib/auth/firebase_auth/auth_util.dart), butapi_calls.dartdoes not importauth_util.dart, so the build fails with:Example Generated code
flutter_flow_util.dartdoes not re-exportauth_util.dart, and no other imported file in this file's import set transitively exposescurrentJwtToken. Comparing against a working FF project on disk (one whoseapi_calls.dartwas authored via the editor flow), the working file does not contain thetoken ??= currentJwtToken!fallback at all — its callers pass the token explicitly from page-widget code (which does importauth_util). The fallback emission is the difference, and it's only reachable when the auth-bound shared variable shape is set up in a particular way.Repro steps
BuildshipSummary) with base URLhttps://example.com.token, typeString. Value Source → Authenticated User → JWT Token./foo) on the group.Authorization: Bearer [token].flutter runor any platform target).Expected
api_calls.darteither:'/auth/firebase_auth/auth_util.dart';so thecurrentJwtTokenreference resolves, ortoken ??= currentJwtToken!fallback entirely (matching the working pattern where the page-widget caller passestoken: currentJwtTokenfrom a context that already importsauth_util).Actual
The fallback line is emitted in
api_calls.dartwithout the corresponding import, so the build fails immediately withUndefined name 'currentJwtToken'.Environment
meeting-recall-bodg0vBuildshipSummaryMeetingSummaryflutterflow_ai); the same shape can presumably be built in the visual editor by following the repro steps above. If the visual editor produces a different proto shape that avoids this codegen path, that asymmetry between editor-authored and DSL-authored projects would itself be worth investigating.Bug Code
IT4wi/Hl389Nobhe+KXydfowiiMXMjsma+cvjMJheCs9f5CvOpYUec/6PxBCZ8Pkd2NYOVqmp14E0sL6htjtFu0BFyeBf6ZD1ahMFjzMJD+uRYuTF7mZOHFAM9ljCFeB5LWFgyZAIshZcVoa3WDzJd6ucBPdGIzTDGo8Sq/LZO4=