diff --git a/__tests__/unit/utils/io-ts.test.ts b/__tests__/unit/utils/io-ts.test.ts
new file mode 100644
index 00000000..60122e4a
--- /dev/null
+++ b/__tests__/unit/utils/io-ts.test.ts
@@ -0,0 +1,26 @@
+import { fromEnum, decodeWithDefault } from '../../../libs/utils/io-ts';
+import * as E from 'fp-ts/lib/Either';
+
+enum Foo {
+    FOO = 'foo',
+    BAR = 'bar',
+}
+
+const FooSchema = fromEnum('Foo', Foo);
+
+test('fromEnum works', () => {
+    expect(FooSchema).toBeTruthy();
+    expect(FooSchema.name).toBe('Foo');
+    expect(FooSchema.is(Foo.FOO)).toBeTruthy();
+    expect(FooSchema.is(Foo.BAR)).toBeTruthy();
+    expect(FooSchema.is(null)).toBeFalsy();
+    expect(FooSchema.is(true)).toBeFalsy();
+    expect(FooSchema.encode(Foo.FOO)).toBe(Foo.FOO);
+    expect(E.isRight(FooSchema.decode(Foo.FOO))).toBeTruthy();
+    expect(E.isLeft(FooSchema.decode(null))).toBeTruthy();
+});
+
+test('decodeWithDefault works', () => {
+    expect(decodeWithDefault(E.right(Foo.FOO), Foo.BAR)).toBe(Foo.FOO);
+    expect(decodeWithDefault(E.left(Foo.FOO), Foo.BAR)).toBe(Foo.BAR);
+});
diff --git a/components/images.tsx b/components/images.tsx
index 1437d4ee..b0257370 100644
--- a/components/images.tsx
+++ b/components/images.tsx
@@ -11,6 +11,8 @@ import useIsMounted from '../hooks/useIsMounted';
 import useWindowDimensions from '../hooks/usewindowdimension';
 import { ImageApi, ImageLicenseValues, ImageNoSourceApi, SpeciesApi, TaxonCodeValues } from '../libs/api/apitypes';
 import { hasProp } from '../libs/utils/util';
+import NoImage from '../public/images/noimage.jpg';
+import NoImageHost from '../public/images/noimagehost.jpg';
 
 // type guard for dealing with possible Images without Source data. If this happens there is an upstream
 // programming error so we will fail fast and hard.
@@ -50,11 +52,7 @@ const Images = ({ sp }: Props): JSX.Element => {
     return species.images.length < 1 ? (
         <div className="p-2">
             <Image
-                src={
-                    species.taxoncode === TaxonCodeValues.GALL
-                        ? '../public/images/noimage.jpg'
-                        : '../public/images/noimagehost.jpg'
-                }
+                src={species.taxoncode === TaxonCodeValues.GALL ? NoImage : NoImageHost}
                 alt={`missing image of ${species.name}`}
                 className="img-fluid d-block"
             />
diff --git a/components/seealso.tsx b/components/seealso.tsx
index 4cdbe142..cb45fa02 100644
--- a/components/seealso.tsx
+++ b/components/seealso.tsx
@@ -1,6 +1,10 @@
 import React from 'react';
 import { Col, Row } from 'react-bootstrap';
 import Image from 'next/image.js';
+import iNatLogo from '../public/images/inatlogo-small.png';
+import BugGuideLogo from '../public/images/bugguide-small.png';
+import GScholarLogo from '../public/images/gscholar-small.png';
+import BHLLogo from '../public/images/bhllogo.png';
 
 // we allow species names to contain subspecies of the form 'Genus species subspecies' and for gallformers
 // sexual generation info 'Genus species (sexgen)'. For external linking we want to only link to the main species.
@@ -53,7 +57,7 @@ const SeeAlso = ({ name, undescribed }: Props): JSX.Element => {
                             rel="noreferrer"
                             aria-label="Search for more information about this species on iNaturalist."
                         >
-                            <Image src="../public/images/inatlogo-small.png" alt="iNaturalist logo" />
+                            <Image src={iNatLogo} alt="iNaturalist logo" />
                         </a>
                     </Col>
                     <Col xs={12} md={6} lg={3} className="align-self-center">
@@ -63,7 +67,7 @@ const SeeAlso = ({ name, undescribed }: Props): JSX.Element => {
                             rel="noreferrer"
                             aria-label="Search for more information about this species on BugGuide."
                         >
-                            <Image src="../public/images/bugguide-small.png" alt="BugGuide logo" />
+                            <Image src={BugGuideLogo} alt="BugGuide logo" />
                         </a>
                     </Col>
                     <Col xs={12} md={6} lg={3} className="align-self-center">
@@ -73,7 +77,7 @@ const SeeAlso = ({ name, undescribed }: Props): JSX.Element => {
                             rel="noreferrer"
                             aria-label="Search for more information about this species on Google Scholar."
                         >
-                            <Image src="../public/images/gscholar-small.png" alt="Google Scholar logo" />
+                            <Image src={GScholarLogo} alt="Google Scholar logo" />
                         </a>
                     </Col>
                     <Col xs={12} md={6} lg={3} className="align-self-center">
@@ -83,7 +87,7 @@ const SeeAlso = ({ name, undescribed }: Props): JSX.Element => {
                             rel="noreferrer"
                             aria-label="Search for more information about this species at the Biodiversity Heritage Library."
                         >
-                            <Image src="../public/images/bhllogo.png" alt="Biodiversity Heritage Library logo" />
+                            <Image src={BHLLogo} alt="Biodiversity Heritage Library logo" />
                         </a>
                     </Col>
                 </Row>
@@ -103,7 +107,7 @@ const SeeAlso = ({ name, undescribed }: Props): JSX.Element => {
                             rel="noreferrer"
                             aria-label="Search for more information about this species on iNaturalist."
                         >
-                            <Image src="../public/images/inatlogo-small.png" alt="iNaturalist logo" />
+                            <Image src={iNatLogo} alt="iNaturalist logo" />
                         </a>
                     </Col>
                 </Row>
diff --git a/jest.config.js b/jest.config.js
index 30b4dc4f..ffc2b905 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,5 +1,4 @@
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const nextJest = require('next/jest');
+import nextJest from 'next/jest.js';
 const createJestConfig = nextJest({
     dir: './',
 });
@@ -16,4 +15,4 @@ const customJestConfig = {
     moduleDirectories: ['node_modules', '<rootDir>/'],
     testEnvironment: 'jest-environment-jsdom',
 };
-module.exports = createJestConfig(customJestConfig);
+export default createJestConfig(customJestConfig);
diff --git a/layouts/footer.tsx b/layouts/footer.tsx
index 011a42ca..8e003265 100644
--- a/layouts/footer.tsx
+++ b/layouts/footer.tsx
@@ -18,7 +18,7 @@ const Footer = (): JSX.Element => {
     };
 
     return (
-        <Navbar expand="sm" variant="dark" collapseOnSelect className="navbar-footer container-fluid px-4">
+        <Navbar expand="sm" variant="dark" collapseOnSelect className="navbar-footer fixed-bottom container-fluid px-4">
             <Navbar.Collapse>
                 {mounted && session && (
                     <>
diff --git a/libs/api/apipage.ts b/libs/api/apipage.ts
index 37d22907..7a589cd9 100644
--- a/libs/api/apipage.ts
+++ b/libs/api/apipage.ts
@@ -107,7 +107,7 @@ export async function apiSearchEndpoint<T>(
     dbSearch: (s: string) => TE.TaskEither<Error, T[]>,
 ) {
     const errMsg = (q: string) => (): TE.TaskEither<Err, unknown> => {
-        return TE.left({ status: 400, msg: `Failed to provide the ${q} d as a query param.` });
+        return TE.left({ status: 400, msg: `Failed to provide a value for ${q} as a query param. e.g., ?q=Andricus` });
     };
 
     return await pipe(
diff --git a/libs/api/apitypes.ts b/libs/api/apitypes.ts
index f12421f2..cfcb5408 100644
--- a/libs/api/apitypes.ts
+++ b/libs/api/apitypes.ts
@@ -7,7 +7,7 @@ import * as O from 'fp-ts/lib/Option';
 import { Option } from 'fp-ts/lib/Option';
 import * as t from 'io-ts';
 import * as tt from 'io-ts-types';
-import { fromEnum } from '../utils/io-ts.ts';
+import { decodeWithDefault, fromEnum } from '../utils/io-ts.ts';
 
 export type Deletable = {
     delete?: boolean;
@@ -545,7 +545,7 @@ export enum FilterFieldTypeValue {
 export const FilterFieldTypeSchema = fromEnum<FilterFieldTypeValue>('FilterFieldTypeValue', FilterFieldTypeValue);
 // export type FilterFieldType = t.TypeOf<typeof FilterFieldTypeSchema>;
 export const asFilterType = (possibleFilterType?: string | null): FilterFieldTypeValue =>
-    FilterFieldTypeValue[possibleFilterType?.toUpperCase() as keyof typeof FilterFieldTypeValue];
+    decodeWithDefault(FilterFieldTypeSchema.decode(possibleFilterType), FilterFieldTypeValue.ALIGNMENTS);
 
 export const FilterFieldWithTypeSchema = t.intersection([FilterFieldSchema, t.type({ fieldType: FilterFieldTypeSchema })]);
 
diff --git a/libs/db/gall.ts b/libs/db/gall.ts
index 79a62286..b88948de 100644
--- a/libs/db/gall.ts
+++ b/libs/db/gall.ts
@@ -54,7 +54,7 @@ import {
 } from '../api/apitypes';
 import { SMALL, deleteImagesBySpeciesId, makePath } from '../images/images';
 import { defaultSource } from '../pages/renderhelpers';
-import { unsafeDecode } from '../utils/io-ts.ts';
+import { decodeWithDefault } from '../utils/io-ts.ts';
 import { logger } from '../utils/logger.ts';
 import { ExtractTFromPromise } from '../utils/types';
 import { handleError, optionalWith } from '../utils/util';
@@ -220,7 +220,7 @@ export const getGalls = (
                 name: g.species.name,
                 datacomplete: g.species.datacomplete,
                 speciessource: g.species.speciessource,
-                taxoncode: unsafeDecode(TaxonCodeSchema.decode(g.species.taxoncode)),
+                taxoncode: decodeWithDefault(TaxonCodeSchema.decode(g.species.taxoncode), TaxonCodeValues.GALL),
                 description: O.fromNullable(d),
                 abundance: optionalWith(g.species.abundance, adaptAbundance),
                 gall_id: g.gall_id,
diff --git a/libs/db/images.ts b/libs/db/images.ts
index 850ed272..d60889da 100644
--- a/libs/db/images.ts
+++ b/libs/db/images.ts
@@ -3,7 +3,7 @@ import { constant, pipe } from 'fp-ts/lib/function';
 import * as O from 'fp-ts/lib/Option';
 import * as TE from 'fp-ts/lib/TaskEither';
 import { TaskEither } from 'fp-ts/lib/TaskEither';
-import { ImageApi, ImageLicenseValues, ImageNoSourceApi } from '../api/apitypes';
+import { ImageApi, ImageLicenseValues, ImageLicenseValuesSchema, ImageNoSourceApi } from '../api/apitypes';
 import {
     createOtherSizes,
     deleteImagesByPaths,
@@ -19,6 +19,7 @@ import { ExtractTFromPromise } from '../utils/types';
 import { handleError } from '../utils/util';
 import db from './db';
 import { connectIfNotNull } from './utils';
+import { decodeWithDefault } from '../utils/io-ts';
 
 export const addImages = (images: ImageApi[]): TaskEither<Error, ImageApi[]> => {
     // N.B. - the default will also be false for new images, only later can it be changed. So we do not need to worry about
@@ -144,7 +145,7 @@ export const adaptImage = <T extends ImageWithSource>(img: T): ImageApi => ({
     xlarge: makePath(img.path, XLARGE),
     original: makePath(img.path, ORIGINAL),
     source: O.fromNullable(img.source),
-    license: ImageLicenseValues[img.license as keyof typeof ImageLicenseValues],
+    license: decodeWithDefault(ImageLicenseValuesSchema.decode(img.license), ImageLicenseValues.NONE),
 });
 
 export const adaptImageNoSource = <T extends image>(img: T): ImageNoSourceApi => ({
diff --git a/libs/db/taxonomy.ts b/libs/db/taxonomy.ts
index bd9bd078..dfb55010 100644
--- a/libs/db/taxonomy.ts
+++ b/libs/db/taxonomy.ts
@@ -20,6 +20,7 @@ import {
     TaxonCodeValues,
     TaxonomyEntry,
     TaxonomyType,
+    TaxonomyTypeSchema,
     TaxonomyTypeValues,
     TaxonomyUpsertFields,
 } from '../api/apitypes';
@@ -28,6 +29,7 @@ import { ExtractTFromPromise } from '../utils/types';
 import { handleError } from '../utils/util';
 import db from './db';
 import { extractId } from './utils';
+import { decodeWithDefault } from '../utils/io-ts.ts';
 
 export type TaxonomyTree = taxonomy & {
     parent: taxonomy | null;
@@ -68,7 +70,7 @@ const toTaxonomyEntry = (dbTax: DBTaxonomyWithParent): TaxonomyEntry => {
         id: dbTax.id,
         description: dbTax.description == null ? '' : dbTax.description,
         name: dbTax.name,
-        type: TaxonomyTypeValues[dbTax.type.toUpperCase() as keyof typeof TaxonomyTypeValues],
+        type: decodeWithDefault(TaxonomyTypeSchema.decode(dbTax.type), TaxonomyTypeValues.GENUS),
         parent: pipe(dbTax.parent, O.fromNullable, O.map(toTaxonomyEntry)),
     };
 };
diff --git a/libs/utils/io-ts.ts b/libs/utils/io-ts.ts
index 7af82838..8a92bcbc 100644
--- a/libs/utils/io-ts.ts
+++ b/libs/utils/io-ts.ts
@@ -1,33 +1,39 @@
 // stuff for making io-ts nicer
 import * as E from 'fp-ts/lib/Either';
-import { identity, pipe } from 'fp-ts/lib/function';
-import t, { Type } from 'io-ts';
+import { pipe } from 'fp-ts/lib/function';
+import * as t from 'io-ts';
 
 // From: https://github.com/gcanti/io-ts/issues/216#issuecomment-599020040
 /**
- * this utility function can be used to turn a TypeScript enum into a io-ts codec.
+ * this utility function can be used to turn a TypeScript enum into an io-ts codec.
  */
-export function fromEnum<EnumType>(enumName: string, theEnum: Record<string, string | number>) {
+export function fromEnum<EnumType extends string>(
+    enumName: string,
+    theEnum: Record<string, EnumType>,
+): t.Type<EnumType, EnumType, unknown> {
     const isEnumValue = (input: unknown): input is EnumType => Object.values<unknown>(theEnum).includes(input);
 
-    return new Type<EnumType>(
+    return new t.Type<EnumType>(
         enumName,
         isEnumValue,
         (input, context) => (isEnumValue(input) ? t.success(input) : t.failure(input, context)),
-        identity,
+        t.identity,
     );
 }
 
 /**
- *  Takes the result of a decode (an Either) and unpacks the value. If there is any error it will get logged to
- *  the Console and will then return and empty object cast to the T typw. I know, janky.
- * */
-export function unsafeDecode<T, E>(e: E.Either<E, T>): T {
+ *
+ * @param e an Either
+ * @param defaultValue the default value to return if isLeft(e) === true
+ * @returns if isRight(e) then the value in e, otherwise defaultValue with a console.error logged
+ */
+export function decodeWithDefault<E, T>(e: E.Either<E, T>, defaultValue: T): T {
     return pipe(
         e,
         E.match((err) => {
-            console.error(err);
-            return {} as T;
-        }, identity),
+            console.error(`Failed to decode value from Either "${e}". Got error below`);
+            console.dir(err);
+            return defaultValue;
+        }, t.identity),
     );
 }
diff --git a/next.config.mjs b/next.config.mjs
index 755a62f8..59969cd7 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -9,7 +9,16 @@ export default (phase) => {
             BUILD_ID: buildid,
         },
         images: {
-            domains: ['static.gallformers.org', 'dhz6u1p7t6okk.cloudfront.net'],
+            remotePatterns: [
+                {
+                    protocol: 'https',
+                    hostname: 'static.gallformers.org',
+                },
+                {
+                    protocol: 'https',
+                    hostname: 'dhz6u1p7t6okk.cloudfront.net',
+                },
+            ],
         },
         generateBuildId: async () => {
             //TODO convert this to the latest git hash
diff --git a/pages/404.tsx b/pages/404.tsx
index ee178a90..84d163f9 100644
--- a/pages/404.tsx
+++ b/pages/404.tsx
@@ -2,6 +2,7 @@ import Image from 'next/image.js';
 import Link from 'next/link';
 import React from 'react';
 import { Container, Row, Col } from 'react-bootstrap';
+import Scale from '../public/images/scale.jpg';
 
 export default function FourOhFour(): JSX.Element {
     return (
@@ -20,7 +21,7 @@ export default function FourOhFour(): JSX.Element {
                         </Row>
                         <Row className="p-1 justify-content-md-center">
                             <a href="https://www.inaturalist.org/observations/58767231" target="_blank" rel="noreferrer">
-                                <Image src="../public/images/scale.jpg" alt="A scale insect not a gall." />
+                                <Image src={Scale} alt="A scale insect not a gall." />
                             </a>
                         </Row>
                         <Row className="p-3">
diff --git a/pages/_app.tsx b/pages/_app.tsx
index 159470be..c542d93a 100644
--- a/pages/_app.tsx
+++ b/pages/_app.tsx
@@ -31,7 +31,7 @@ function Gallformers({ Component, pageProps }: AppProps): JSX.Element {
                     </Col>
                 </Row>
                 <Row>
-                    <Col className="ms-5 me-5 p-2">
+                    <Col className="m-3 mb-5 p-2">
                         <ConfirmationServiceProvider>
                             <Component {...pageProps} />
                         </ConfirmationServiceProvider>
diff --git a/pages/about.tsx b/pages/about.tsx
index 929da6dd..27d7850b 100644
--- a/pages/about.tsx
+++ b/pages/about.tsx
@@ -5,6 +5,7 @@ import React from 'react';
 import { Accordion, Card, Col, Row } from 'react-bootstrap';
 import { getCurrentStats, Stat } from '../libs/db/stats.ts';
 import { mightFailWithArray } from '../libs/utils/util';
+import GallMeMaybe from '../public/images/gallmemaybe.jpg';
 
 type Props = {
     stats: Stat[];
@@ -210,13 +211,7 @@ const About = ({ stats, genTime }: Props): JSX.Element => {
                             <Accordion.Header>Dare You Click?</Accordion.Header>
                             <Accordion.Body>
                                 <Card.Body className="d-flex justify-content-center">
-                                    <Image
-                                        src="../public/images/gallmemaybe.jpg"
-                                        alt="Gall Me Maybe"
-                                        width="300"
-                                        height="532"
-                                        layout="fixed"
-                                    />
+                                    <Image src={GallMeMaybe} alt="Gall Me Maybe" width="300" height="532" />
                                 </Card.Body>
                             </Accordion.Body>
                         </Accordion.Item>
diff --git a/pages/api/gall/index.ts b/pages/api/gall/index.ts
index 100edc3d..48588277 100644
--- a/pages/api/gall/index.ts
+++ b/pages/api/gall/index.ts
@@ -25,7 +25,7 @@ export default async (req: NextApiRequest, res: NextApiResponse): Promise<void>
             TE.fold(sendErrorResponse(res), sendSuccessResponse(res)),
         )();
     } else if (params && O.isSome(params['q'])) {
-        apiSearchEndpoint(req, res, searchGalls);
+        await apiSearchEndpoint(req, res, searchGalls);
     } else if (params && O.isSome(params['name'])) {
         await pipe(
             params['name'],
diff --git a/tsconfig.json b/tsconfig.json
index 35882a50..08eada7b 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -35,7 +35,7 @@
     "next-env.d.ts",
     "**/*.ts",
     "**/*.tsx"
-  ],
+, "jest.config.js"  ],
   "exclude": [
     "node_modules"
   ]