// Example of the warning:
// FlowScript knows that x is not equal to null.
// The warning indicates that the comparison will always be false.
let x : number? = 1;
if x == null {
// ...
}
Value is known to be null (warning)
The value is known to be null here.
// Example of the warning:
// FlowScript knows that x is equal to null. The warning indicates
// that the comparison will always be true.
let x : number? = null;
if x == null {
// ...
}
Missing expected field
Expected field <name> of type <type name>
type Country = { name: text, isoCode: text }
// Example of the error: the "name" field is missing.
return new Country { isoCode: 'bt' }
Generic function must be specialized
The function is generic and the argument types cannot be inferred from usage.
// Example of the error: JSON.deserialize requires a type argument.
return JSON.deserialize("[1, 2]");
// Example resolution: supply the type argument
return JSON.deserialize<number*>("[1, 2]");
default() is not supported for type variables
The default keyword cannot be used with type variables.
// Example of the error: we cannot use the "default"
// keyword with type variables.
function getDefault<T>() => default(T)
Function is not generic
The function is not generic and cannot accept type arguments.
let xs = [1, 2];
// Example of the error: supplying a type argument to a non-generic function.
return count<number>(xs);
// Example resolution: remove the type arguments.
return count(xs);
Type mismatch
Expected a <A>, but the term has type <B>.
// Example: update a variable with the wrong type.
let x = 1;
set x = false;
Operator type mismatch
The operator <operator> cannot be used with types <A> and <B>.
let x = "3";
let y = "1";
// Example of the error: trying to subtract a text value from a text value.
return x - y;
// Example resolution: convert both sides to numbers
return val(x) - val(y);
Argument type mismatch
Argument <name> was expected to have type <A>, but the expression has type <B>.
let x = "1";
let y = 2;
// Example of the error:
// The first argument to the 'max' function is not a number.
return max(x, y);
// Example resolution: convert x to a number.
return max(val(x), y);
Wrong argument count
Incorrect number of arguments for function <function signature>.
// Example of the error:
// Pass too many arguments to the 'max' function. (It only accepts exactly two.)
return max(1, 2, 3);
Unknown member
The type does not contain a field labelled <name> and no matching self function was found.
let user = {id: 0, name: 'Ismail'};
// Example of the error:
// Access a record member which does not exist.
return user.email;
Value is not a record
The value is not a record.
// Example 1: forgetting to use parentheses with a self function.
return [1, 2].count;
// Example 1 resolution: call the self function.
return [1, 2].count();
// Example 2: using dot notation with a non record.
return "1".id;
Wrong arity of type constructor
The type <name> requires <number> type arguments.
type Box<T> = { contents: T }
// Example of the error: Box<T> has arity 1, but two arguments are supplied.
type BooleanShipment = { box: Box<boolean, boolean>, address: text }
Duplicate field
The field label <label> occurs more than once.
// Example of the error: a record where the "name" field occurs twice.
return {
name: "greta",
name: "coco"
}
Duplicated type argument
The function has duplicated type arguments.
// Example of the error: the function has two type arguments by the same name
function foo<T, T>() {
// ...
}
Duplicated parameter name
The parameter <name> occurs more than once.
// Example of the error: the function has two parameters called "x"
function compare(x: number, x: number) {
// ...
}
Cyclic reference in type
The type involves an immediate cyclic reference.
// Example of the error: Company contains a Company which contains a Company...
type Company = { name: text, parent: Company }
// Example resolution: make the cyclic reference nullable.
type Company = { name: text, parent: Company? }
Multiple nullability annotations (warning)
The type is already nullable.
// Example: a doubly nullable type.
type NullableBoolean = boolean?;
type NullableNullableBoolean = NullableBoolean?;
Type is not a record type
The type is not a record type.
// Example of the error: use the 'new' syntax with a sequence type
type UserTable = {id: number, name: text}*; // note the sequence star
return new UserTable {
id: 0,
name: 'George'
}
Impossible type narrowing
The type narrowing expression will always be false.
let user = {id: 0, name: "Ljudmila"}
// Example of the error: FlowScript knows that 'user' could never be a number.
if user is number {
// ...
}
Truistic type narrowing
The type narrowing expression will always be true.
let x = 1;
// Example of the error: FlowScript knows that 'x' is always a number.
if x is number {
// ...
}
Control flow errors
Identifier already declared
The identifier <name> is already declared.
// Example 1: "count" is the name of a built-in function.
let count = 1;
// Example 2: declaring the same variable twice.
let x = 1;
let x = 2;
Unknown variable
The variable <name> does not exist or cannot be used in this context.
// Example of the error:
// Access a variable which does not exist.
return foo + 1;
Unknown type
The type <name> does not exist.
// Example of the error: access a type which does not exist.
let user = {id: 0, name: 'Farah'};
if x is User {
// ...
}
Variable is read-only
The variable <name> is read-only in this scope.
// Example of the error: we can only update the value of local variables,
// i.e. variables declared in the same script.
set count = 2;
Continue only allowed in loops
The continue statement is only allowed in the body of loops.
// Example of the error: "continue" has no meaning outside of a loop body.
let x = 1;
continue;
Break only allowed in loops
The break statement is only allowed in the body of loops.
// Example of the error: "break" has no meaning outside of a loop body.
let x = 1;
break;
Type already declared
The type <name> is already declared.
// Example of the error:
// declare the "User" type twice.'
type User = {id: number, name: text};
type User = {id: number, name: text, email: text};
Not all paths return a value
Not all paths return a value.
// Example of the error:
// A function which does not always return.
function absolute(x: number) {
if x < 0:
return x * -1;
}
// Example resolution: add a return statement on the path where it is missing.
function absolute(x: number) {
if x < 0:
return x * -1;
else:
return x;
}
Type cannot be used with loops
The term has type <type> and cannot be used with for loops or queries.
let user = {id: 0, name: 'Jacinto'};
// Example: trying to loop over a record
for x in user {
// ...
}
// Example resolution: turn the record into a sequence of members
for x in Record.getMembers(user) {
// ...
]
Cannot declare type inside loop or conditional block
Types cannot be declared inside loops or conditional blocks.
let response = HTTP.getText("https://example.com/api/users/1", {});
// Example of the error: a type declared in a loop.
if response.statusCode == 200 {
type User = {id: number, name: text};
return JSON.deserialize<User>(response.contents);
}
// Example resolution: move the type definition to the root level.
type User = {id: number, name: text};
if response.statusCode == 200 {
return JSON.deserialize<User>(response.contents);
}
Module not found
The module <name> is not declared.
// Example of the error: open a non-existent module
open Hello;
Statement in module
Modules can only contain functions and type definitions.
// Example of the error: doing any kind of work in a module.
let result = HTTP.get("https://www.example.com", {});
Query errors
Ambiguous join condition
The join condition has ambiguous identifiers; use an alias to resolve.
let table = [{a: 1, b: 2}, {a: 2, b: 3}];
let other = [{a: 1, c: 2}, {a: 4, c: 5}];
// Example of the error: label "a" exists in both "table" and "other"
return select b from table join other on a = a;
// Example resolution: add aliases to both "table" and "other"
return select b from table as t join other as o on t.a = o.a;
Wildcard in joint selection
The wildcard (*) is not supported when joining two sequences. Specify the columns explicitly instead.
let users = [
{id: 0, name: 'bob', departmentId: 0},
{id: 1, name: 'alice', departmentId: 1}
];
let departments = [
{id: 0, name: 'Finance'},
{id: 1, name: 'R&D'}
];
// Example of the error: wildcard selection not supported with joins
return select * from users as u
left join departments as d
on u.departmentId = d.id;
// Example resolution: specify the columns explicitly.
return select u.id, u.name, d.name as departmentName
from users as u
left join departments as d
on u.departmentId = d.id;'
Wildcard in grouped selection
The wildcard (*) is not supported when grouping a sequence. Specify the columns explicitly instead.
let table = [{a:1, b:2}, {a: 1, b: 2}, {a: 1, b: 5}, {a: 2, b: 5}];
// Example of the error: wildcard selection not supported with groups
return select * from table group by a
// Example resolution: specify the columns explicitly
return select a, count(b) as b
from table group by a
Ambiguous reference in query
The identifier is ambiguous; use an alias to resolve.
let table = [{a: 1, b: 2}, {a: 2, b: 3}];
let other = [{a: 1, c: 2}, {a: 4, c: 5}];
// Example of the error: "a" in the where clause exists in both sequences
return select b
from table
join other on b = c
where a = 1;
// Example resolution: use an alias to disambiguate
return select b
from table as t
join other as o
on t.b = o.c
where t.a = 1;
Type is not queryable
The type <type name> cannot be used with query operators.
// Example of the error: we cannot query a record.
let user = {id: 0, name: 'Francesca'}
return user where id = 0;
Missing alias
The expression contains no implicit field name. Specify one with the 'as' keyword.
// Example of the error:
// FlowScript cannot assign a name to the second column.
return select x, max(x, y)
from [{x: 1, y: 2}]
// Example resolution: specify an alias for the second column
return select x, max(x, y) as maximum
from [{x: 1, y: 2}]
Missing consition on with update
If any clause of a with-expression has a condition, all clauses must have conditions.
let coord = {x: 1, y: 2}
// Example of the error: the second clause has no condition
return coord with {x: x + 1} when y == 0, {x: x - 1};
// Example resolution: add the "otherwise" keyword or a condition.
return coord with {x: x + 1} when y == 0, {x: x - 1} otherwise;
More than one otherwise clause
There may be at most one 'otherwise' clause.
let points = [{x: 1, y: 0}, {x: 0, y: 1}]
// Example of the error: two 'otherwise' clauses.
return points with {y: [1, 2, 3]} when x = 0,
{y: []} otherwise,
{y: [1]} otherwise;
Redundant otherwise clause (warning)
An 'otherwise' clause is only needed in conjunction with 'when' clauses.
let points = [{x: 1, y: 0}, {x: 0, y: 1}]
// Example of the error: the 'otherwise' keyword is not needed here.
return points with {y: [1, 2, 3]} otherwise;
Otherwise clause must come last
An 'otherwise' must be the last clause in a with-expression.
let points = [{x: 1, y: 0}, {x: 0, y: 1}]
// Example of the error: the 'otherwise' clause does not come last.
return points with {y: [1, 2, 3]} otherwise, {y: [2, 3]} when x = 0;